[ 자바스크립트 ] Async, await

김수연·2022년 10월 3일
0
post-thumbnail

비동기 작업 만들기

async 키워드는 함수 선언시에 앞에 붙여준다.
promise 밀접한 연관이 있는데 아래 코드에서 new Promise를 리턴하는 함수를 async 함수로 바꿔보자

// 기존
// function startAsync(age) {
//  return new Promise((resolve, reject) => {
//    if (age > 20) resolve(`${age} success`);    
//   else reject(new Error("Something went wrong"));
//  });
// }

async function startAsync(age) {
  if (age > 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

setTimeout(() => {
  const promise1 = startAsync(25);
  promise1
    .then((value) => {
      console.log(value);
    })
    .catch((error) => {
      console.error(error);
    });
  const promise2 = startAsync(15);
  promise2
    .then((value) => {
      console.log(value);
    })
    .catch((error) => {
      console.error(error);
    });
}, 1000);
25 success
Error: 15 is not over 20
    at startAsync (/home/taehoon/Desktop/playground-nodejs/index.js:11:14)
    at Timeout._onTimeout (/home/taehoon/Desktop/playground-nodejs/index.js:23:20)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

이전 Promise 챕터의 코드와 완벽하게 같은 결과를 보여준다(내부적으로 다를 순 있지만)

🚨 async 함수의 리턴값은 무조건 promise

if (age > 20) return `${age} success`;
else throw new Error(`${age} is not over 20`);

코드 자체만 보면 문자열이 리턴될 것으로 예상할 수 있지만

async function startAsync(age) {
  if (age > 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

const promise1 = startAsync(15)
console.log(typeof promise1); // object
console.dir(promise1) // Promise

짠! async 키워드를 붙인 것만으로 Promise 객체를 리턴하고 있다.
일반 함수처럼 다룰 수 없다는 걸 깨달아 버렸다.. 이제 어떻게 할까?

Promise 객체처럼 then, catch 로 후속처리를 할 수 있지만
새로운 await 키워드를 이용해서 코드를 async 함수를 다뤄보자


await

awaitPromise 가 reject인지 fulfilled인지 상관 없이 일단 끝날 때까지 기다리는 특징을 가지고 있다.

resolve

reject

awaitresolve 함수가 호출될 때까지 기다린다.
reject 가 호출됐을 땐 pending 상태에 머물러 있음을 알 수 있다.


더 자세한 예제를 통해 await을 알아보자

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

async function startAsync(age) {
// 리턴한 값은 resolve, reject에 해당하는 값은 error 로 해결
  
  if (age > 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

async function startAsyncJobs() {
  await setTimeoutPromise(1000);
  
  const promise1 = startAsync(25);
  try {
    const value1 = await promise1; // *
    console.log(value1);
  } catch (e) {
    console.error(e);
  }
  const promise2 = startAsync(15);
  try {
    const value2 = await promise2; // *
    console.log(value2);
  } catch (e) {
    console.error(e);
  }
}

startAsyncJobs();
  1. 문법 : await + Promise 객체
  2. await은 Promise 가 resolve 함수를 호출하기를 기다린다.
  3. ✨ async 함수에서 리턴하는 값을 resolve 값으로 간주한다.
value1 // ${age} success
value2 // ${age} is not over 20
  1. throw error 로 처리되는 값이 reject 값으로 간주되고
    catch 절로 넘겨 예외처리한다.

📌 await 의 의의?

비동기 함수로 시작한 작업은 그로부터 파생한 모든 작업도 비동기 작업으로 간주할 수 있다.

이게 무슨 소리지??

말 그대로 동기 환경 에서는 비동기로 처리한 작업을 기다리지 않고 내 할 일을 하고 있기 때문에 비동기 작업 안에서 동기 작업이 발생하는지 신경쓰지 않는다.

하지만 비동기 환경 에서 비동기 작업의 결과를 기다리는 건 의미가 있는데
예를 들어 '이번 달에 생일인 친구들의 목록을 받아온 뒤 생일 파티를 준비' 하려면 일단 이번 달 생일인 친구들을 찾아내서 결과를 받아야 한다.
무작정 아무 친구나 생일 준비를 해줄 수 없으니 말이다.

이럴 때 await 을 사용하는 것이다.

Promise 작업 끝남 
	-> 후속 조치 
       -> resolve : then  
       -> reject : catch
       
		|
		|
     await 함수
		|
		↓

Promise 작업 진행
	-> resolve를 기다림(await)
        - 원하는 코드 실행
    -> reject로 error 발생
    	- catch 로 예외 처리   

작업이 끝나고 후속처리를 하는 방법대신
하나의 async 흐름에서 기다렸다가 다음 코드를 실행하는, 우리가 그동안 해온 느낌으로 비동기 작업을 다룰 수 있게 된다!


출처:

https://elvanov.com/2597 - [Javascript] 비동기, Promise, async, await 확실하게 이해하기

profile
길을 찾고 싶은 코린이 of 코린이

0개의 댓글