[모던 JavaScript 튜토리얼] - [11.8] async와 await

IRISH·2024년 2월 8일
0

JS

목록 보기
67/80



학습 내용

function 앞에 async 키워드를 추가하면 두 가지 효과가 있습니다.

  1. 함수는 언제나 프라미스를 반환합니다.
  2. 함수 안에서 await를 사용할 수 있습니다.

프라미스 앞에 await 키워드를 붙이면 자바스크립트는 프라미스가 처리될 때까지 대기합니다. 처리가 완료되면 조건에 따라 아래와 같은 동작이 이어집니다.

  1. 에러 발생 – 예외가 생성됨(에러가 발생한 장소에서 throw error를 호출한 것과 동일함)
  2. 에러 미발생 – 프라미스 객체의 result 값을 반환

async/await를 함께 사용하면 읽고, 쓰기 쉬운 비동기 코드를 작성할 수 있습니다.

async/await를 사용하면 promise.then/catch가 거의 필요 없습니다. 하지만 가끔 가장 바깥 스코프에서 비동기 처리가 필요할 때같이 promise.then/catch를 써야만 하는 경우가 생기기 때문에 async/await가 프라미스를 기반으로 한다는 사실을 알고 계셔야 합니다.

여러 작업이 있고, 이 작업들이 모두 완료될 때까지 기다리려면 Promise.all을 활용할 수 있다는 점도 있습니다.

실습 코드

⇒ async 함수

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

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

⇒ await

async function f() {

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

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

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

f();
  • 일반 함수에는 await 사용 불가!

⇒ 에러 핸들링

async function f() {

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

f();

과제

async와 await를 사용하여 코드 변경하기

프라미스 체이닝 챕터의 예시 중 하나를 .then/catch 대신 async/await를 사용해 다시 작성

⇒ 문제

function loadJson(url) {
  return fetch(url)
    .then(response => {
      if (response.status == 200) {
        return response.json();
      } else {
        throw new Error(response.status);
      }
    })
}

loadJson('no-such-user.json')
  .catch(alert); // Error: 404

⇒ 해답

async function loadJson(url) { // (1)
  let response = await fetch(url); // (2)

  if (response.status == 200) {
    let json = await response.json(); // (3)
    return json;
  }

  throw new Error(response.status);
}

loadJson('no-such-user.json')
  .catch(alert); // Error: 404 (4)

설명:

  1. 함수 loadJson은 async 함수가 됩니다.

  2. 함수 안의 .then을 전부 await로 바꿉니다.

  3. 위 답안처럼 await를 사용해도 되지만, 아래처럼 return response.json()를 사용해도 됩니다.

    대신, 이렇게 작성하면 프라미스가 이행되는걸 await를 사용해 바깥 코드에서 기다려야 합니다. 위 예시는 해당 사항이 없지만 말이죠.

if (response.status == 200) {
	return response.json(); // (3)
}
  1. loadJson에서 던져진 에러는 .catch에서 처리됩니다. loadJson을 호출하는 코드는 async 함수 내부가 아니기 때문에 await loadJson(…)을 사용할 수 없습니다.

느낀점

회사에서 다른 프로젝트에 참여하고 있는 인원의 코드를 본적이 있었다. 거기에서는 async 이 되게 많이 있었다.

물어보니까, 본인이 작성한 것은 아니고 해당 프로젝트를 운영하기 위해 구매를 진행했는데, 운영 프로그램에 이미 담겨져 넘긴 내용이었다.

그렇다고 하더라도, async은 분명 많이 다룰 가능성이 높다고 생각했고, 이참에 이론이나마 배워야 되겠다고 생각했다.

async을 사용하면, Promise의 사용률이 현저히 줄어들고, 이에 따라 코드 단순화도 더 쉬울 것 같다.

profile
#Software Engineer #IRISH

0개의 댓글