[실전 자바스크립트] async await

주수호·2022년 5월 15일
0

async

비동기 프로그래밍을 동기 프로그래밍의 방식으로 작성하는데에 특화되어진 문법입니다.

Promise의 then사용 방식보다 가독성이 더 좋으나, Promise는 반환하는 비동기상태값에 대한 제어가 가능하기 때문에, 좀 더 포괄적인 개념을 가진다고 볼 수 있습니다.


async function getData() {
  return 123;
}

getData().then((data) => console.log(data));

async await에서 반환하는 값은 promise입니다. 그렇기 때문에 그 상태와 데이터를 그대로 반환할 수 있습니다.

async function getData() {
  return Promise.resolve(123);
  //return Promise.reject(123); 만약이렇게 reject를 넘겨준다면, catch부분이 실행 될 겁니다.
}

getData()
  .then((data) => console.log("fulfilled", data))
  .catch((data) => console.log("rejected", data));

위처럼 넘겨주는 promise의 상태값에 따른 처리가 가능한 코드를 작성할 수 있습니다.


await

async 를 사용하는 함수 내부에서는 await를 사용하는 것이 가능합니다.

await 키워드 오른쪽에 Promise객체를 입력하게 되면, 해당 promise객체가 settled가 될 때까지 기다리게 됩니다.

fullfilled(제대로 진행) 됐을 때에는 지정한 변수에 해당 값이 들어가게 됩니다.

async function printData() {
  const data1 = await requestData(10);
  const data2 = await requestData(20);
  console.log(data1, data2);
}
printData();

// result :: data1함수가 실행 및 끝이나고, 그다음 data2가 실행됩니다.

async awiat는 그 promise의 상태와 데이터를 그대로 반환처리합니다.

async function getData() {
  console.log("getData 1");
  await Promise.reject();
  console.log("getData 2");
  await Promise.resolve();
  console.log("getData 3");
}

getData()
  .then(() => console.log("fulfilled"))
  .catch((error) => console.log("rejected"));

위에서 Promise.reject(); 를 통해 호출이 끝나버리고, reject상태의 promise를 반환하기 때문에, catch의 구문이 동작하게 됩니다.

결과

$ node class.js 
getData 1
rejected

awiat 키워는 async await함수 내부에서만 활용가능합니다.

아래처럼 일반함수에서는 await키워드를 사용할 수 없습니다.

function getData() {
  const data = await requestData(10);
  console.log(data);
}

비동기함수와 비동기함수간의 연계가 높아질수록 async await과 promise의 가독성의 차이가 드러납니다.

function getDataPromise() {
  return asyncFunc1()
    .then((data1) => Promise.all([data1, asyncFunc2(data1)]))
    .then(([data1, data2]) => {
      return asyncFunc3(data1, data2);
    });
}

async function getDataAsync() {
  const data1 = await asyncFunc1();
  const data2 = await asyncFunc2();
  return asyncFunc3(data1, data2);
}

async await에서 여러함수를 병렬로 처리하는 방법은 이와 같습니다.
두개의 promise객체를 생성하여, await키워드를 사용하게되면 병렬로써 실행하게 됩니다.

...
async function getData() {
  const p1 = asyncFunc1();
  const p2 = asyncFunc2();
  const data1 = await p1;
  const data2 = await p2;
  console.log({ data1, data2 });
}

getData();

반대로, Promise객체를 활용하면 이코드가 더 간단해지게 됩니다.

두개의 Promise객체를 매개변수로써 입력하고 있기 때문에 앞전코드처럼 병렬처리가 진행하게 됩니다.

...
async function getData() {
  const [data1, data2] = await Promise.all([asyncFunc1(), asyncFunc2()]);
  //...
}

async await 예외처리하기

이처럼 동기함수와 비동기함수가 공존하는 경우에 대해서는 catch문을 통한 예외처리가 가능하다.

async function getData() {
  try {
    await doAsync();
    return doSync();
  } catch (error) {
    console.log(error);
    return Promise.reject(error);
  }
}

Thenable

then메소드를 사용하는 객체는 promise처럼 취급되어진다. (이를 Thenable이라고 한다.)

await을 통해서 아래처럼 사용하는 것을 확인 할 수 있다.

class ThenableExample {
  then(resolve, reject) {
    setTimeout(() => resolve(123), 1000);
  }
}

async function asyncFunc() {
  const result = await new ThenableExample();
  console.log(result);
}
profile
항상 준비하는 엔지니어

0개의 댓글