JavaScript | Promise, Await, Async

Hyeonju L.·2021년 1월 21일
0

JavaScript

목록 보기
10/10

1. Promise

Promise는 일단 class선언을 먼저해서 실행할 상태를 만들어 두고 필요할 때 callback해서 결과값을 나중에 받는다는 '약속'을 하는 것이다. 즉, 결과값은 실행이 완료된 후 then이나 catch 메소드를 통해 받을 수 있다. promise는 비동기적 작업을 위한 자바스크립트의 객체로 비동기 처리 시 callback함수 대신에 사용된다.
여기서 '비동기 처리'란 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 것을 의미한다.

Promise의 상태

Promise는 다음 중 하나의 상태를 가진다.

  • 대기(pending): 비동기 처리 로직이 진행중인 상태
  • 이행(fulfilled): 비동기 처리가 성공적으로 완료된 상태
  • 거부(rejected): 비동기 처리가 실패하거나 오류가 발생한 상태

Promise 클래스를 생성하면 pending상태가 되며, 이 때 콜백함수를 선언할 수 있고 콜백함수의 인자는 resolve, reject이다.

new Promise((resolve, reject) => {
  // network 통신, DB에서 file 읽어오기 등 heavy work 수행
});

구문 예시

Promise는 producer(정보제공)와 consumer(정보이용)의 두 가지로 구분된다고 볼 수 있다.

// 1. producer
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("amiee")	// Promise가 정상적으로 수행
  }, 2000);	        // 초는 ms단위
})

// 2. Consumer
promise
  .then((value) => {
    console.log(value);
  })
  .catch((error) => {
    console.log(error);
  })
  .finally(() => {
    console.log("finally"); 
  });

then, catch, finally Promise class에서 짜여진 로직에 따라 실행.

  • then promise가 제대로 수행되면 then, 그리고 resolve를 통해 들어온 value return.
  • catch error핸들링. then에서 return된 promise를 catch가 다시 받음.
  • finally resolve, reject와 상관없이 사용.

Promise chaining

Promise chaining은 결과가 .then의 chain을 통해 순차적으로 처리되는 것.

const fetchNumber = new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000)		// 1초 있다가 1 전달
})

fetchNumber
  .then((num) => num*2)	// num에 resolve의 인자인 1이 전달됨 => num = 1*2 = 2
  .then((num) => num*3) // num에 위 .them에서 넘겨받은 인자 전달 => num = 2*3 = 6
  .then((num) => {
	return new Promise((resolve, reject) => {
      setTimeout(() => resolve(num-1), 1000)	// setTimeout은 resolve(5)를 1초 뒤 처리
    });
})
.then((num) => console.log(num));	// 결과 5 (2초 소요)

Error Handling

const getHen = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve("🐔️"), 1000);
  });
const getEgg = (hen) =>
  new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error(`error! ${hen} => 🥚️`)), 1000); //  에러 발생하는 경우(reject)
  });
const cook = (egg) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${egg} => 🍳️`), 1000);
  });

getHen()
  .then(getEgg) // 인자를 받아 동일한 값 출력하는 경우 생략가능 (getEgg) = ((hen) => getEgg(hen))
  .catch((error) => {
    // 계란을 받아올 때 에러가 생기는 경우 처리(중간에 발생하는 에러를 처리해서 요리가 끝까지 완성될 수 있도록 함)
    return "🥖️";
  })
  .then(cook)
  .then(console.log) // 여기도 생략 가능 (console.log) = ((meal) => console.log(meal))
  .catch(console.log);

reference. 드림코딩 by 엘리(Youtube)

2. Await & Async

await, async를 사용하면 promise를 이용한 로직보다 좀 더 깔끔하게 작성할 수 있다.

Promise 로직과 비교

// Promise를 이용한 비동기 로직
function fetchUser() {
  return new Promise((resolve, reject) => resolve("Amiee"));
}

const user = fetchUser()
user.then(console.log)	// 결과: Promise {'Amiee'}
console.log(user)	// 결과: Amiee

// await
async function fetchUser() {
  return "Amiee";
}

const user = fetchUser()
user.then(console.log)	// 결과: Promise {'Amiee'} : async를 쓰면 promise를 쓰지 않아도 함수 내부에서 promise로 인식함.
console.log(user)	// 결과: Amiee

async & await

function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms)); 
}

async function getApple() {
  await delay(2000); // 2초가 지나면 resolve가 호출됨. 
  return "🍎️";	// 2초가 지날때까지 apple을 return해라
}

async function getBanana() {
  await delay(1000);
  return "🍌️";
}

async function pickFruits() {
  const apple = await getApple();
  const banana = await getBanana();
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);	// 결과: 🍎️ + 🍌️ (3초 뒤 출력)

Promise APIs

.all

Promise의 배열을 전달하게 되면 모든 Promise들이 병렬적으로 다 받을 때까지 모아준다.

function pickAllFruits() {
  return Promise.all([getApple(), getBanana()])
    .then(fruits) => fruits.join(" + "); // join: 배열을 string으로 모아주는 method
}
pickAllFruits().then(console.log) // 결과: 🍎️ + 🍌️

.race

Promise의 race API 배열에 전달된 Promise 중 가장 먼저 전달된 promise만 return한다.

function pickOnlyOne() {
  return Promise.race([getApple(), getBanana()]); 
}
pickOnlyOne().then(console.log); // 결과: 🍌️ (1초)
profile
What you think, you become. What you feel, you attract. What you imagine, you create.

0개의 댓글