TIL 87 | async/await 뭐야 이렇게 간단한거였어?

meow·2020년 12월 10일
1

JavaScript

목록 보기
35/46
post-thumbnail

클론 프로젝트를 하면서 async, await를 사용했었는데, 정확히 프라미스의 .then 메서드를 사용하는 것과 어떻게 다른지 이해 없이 그냥 외워서 썼다. 항상 찝찝함이 남아있었는데, 이번 기회에 에이싱크 어웨이트 완전히 뿌셔보리라....... 💥💥💥

나의 최애 멘토님에게 배웠습니다 🎄
Mastering Async/Await 번역문 시리즈

async

async는 function 앞에 위치하는데, 해당 함수는 항상 프라미스를 반환한다.

문법

async function f() {
  return 1;
}

프라미스가 아닌 값을 반환하더라도 resolved promise로 값을 감싸 이행된 프라미스가 반환되게 한다. 따라서 아래 두개의 함수는 동일한 프라미스가 반환된다.

async function f() {
  return 1;
}

f().then(alert); // 1
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

✔︎ async는 반드시 프라미스를 반환한다! 프라미스가 아닌 것은 프라미스로 감싸서 반환한다! so simple! ^0^

await

문법

// await는 async 함수 안에서만 동작합니다.
let value = await promise;

자바스크립트는 await 키워드를 만나면 프라미스가 처리될 때까지 기다린다.

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)

  alert(result); // "완료!"
}

f();

이름처럼 실행이 잠시 '중단' 되었다가 프라미스가 처리되면 실행이 재개된다. 프라미스가 처리되길 기다리는 동안에 엔진이 다른 일(다른 스크립트 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.

✔︎ 일반 함수에는 await 사용 불가! Error 발생!

✔︎ await는 최상위 레벨 코드에서 작동하지 않는다.

// 최상위 레벨 코드에선 문법 에러가 발생함
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();

익명 async 함수로 코드를 감싸면 최상위 레벨 코드에서도 사용할 수 있다.

(async () => {
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();
  ...
})();

✔︎ 메서드 이름 앞에 async를 추가하면 async 클래스 메서드를 선언할 수 있다.

class Waiter {
  async wait() {
    return await Promise.resolve(1);
  }
}

new Waiter()
  .wait()
  .then(alert); // 1

async 메서드와 async 함수는 프라미스를 반환하고 await를 사용할 수 있다는 점에서 동일하다.

에러 핸들링

프라미스가 거부되면 throw문을 작성한 것처럼 에러가 던져진다. 아래 두 코드는 동일하다.

async function f() {
  await Promise.reject(new Error("에러 발생!"));
}
async function f() {
  throw new Error("에러 발생!");
}

await가 던진 에러는 try...catch를 사용해 잡을 수 있다. try 안에는 여러 줄의 코드를 감쌀 수 있다.

async function f() {

  try {
    let response = await fetch('http://유효하지-않은-url');
    let user = await response.json();
  } catch(err) {
    // fetch와 response.json에서 발행한 에러 모두를 여기서 잡습니다.
    alert(err);
  }
}

f();

try...catch가 없으면 async 함수를 호출해 만든 프라미스가 거부된 상태가 된다. .catch를 추가하면 거부된 프라미스를 처리할 수 있지만, 추가하는 것을 잊으면 프라미스 에러가 발생한다.

✔︎ async/awaitPromise.all과 함께 사용하기

// 프라미스 처리 결과가 담긴 배열을 기다립니다.
let results = await Promise.all([
  fetch(url1),
  fetch(url2),
  ...
]);
profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글