[JS] Async & Await

강은비·2022년 1월 3일
0

JS

목록 보기
10/19
post-thumbnail
post-custom-banner

Promise를 통한 비동기 코딩

function fetchAuthorName(postId) {
  return  fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`)
    .then((response) => response.json())
    .then((post) => post.userId)
    .then((userId) => {
      return fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
        .then((response) => response.json())
        .then((user) => user.name);
    });
}

fetchAuthorName(1).then((name) => console.log("name:", name));

❗ 문제점

1) 디버깅이 어렵다.

  • then()을 연쇄적으로 호출하고 있어 몇 번째 then()에서 문제가 발생한 건지 Stack Trace를 보더라도 혼란스러울 수 있다.

2) 예외처리

  • Promise를 사용하면 catch()메서드를 이용하여 예외처리를 해야 한다.
  • 만약 동기 코드와 비동키 코드가 섞여 있을 경우 예외 처리가 난해해지거나 예외 처리를 누락하는 경우가 생기기 쉽다.

3) 들여쓰기

  • 실제 프로젝트에서는 복잡한 구조의 비동기 처리 코드를 작성하게 된다.
  • 따라서, then() 메서드의 인자로 넘기는 콜백함수 내에서 조건문이나 반복문을 사용하거나 여러 개의 Promise를 병렬로 또는 중접해서 호출해야 하는 경우들이 발생한다.
  • 이럴 경우, 다단계 들여쓰기를 해야 할 확률이 높아지며 코드의 가독성이 떨어진다.

async/await 키워드를 통한 비동기 코딩

Promise의 이러한 불편함 점들을 해결하기 위해 ES7에서 async/await 키워드가 추가되었다. 이 키워드를 사용하면 비동기 코드를 마치 동기 코드처럼 보이게 작성할 수 있다.

✨ 기본 문법

async function 함수명() {
  await 비동기_처리_메서드_명();
}
  • 함수 앞에 async라는 예약어를 붙인다.
  • async 키워드가 붙여진 함수 내부의 비동기 함수/메서드 앞에 await 키워드를 붙인다.
    • 이때 비동기 함수/메서드가 반드시 프로미스 객체를 반환해야 하고 비동기 함수/메서드가 리턴하는 Promise로부터 결과값을 추출해준다.
    • await 키워드를 사용하면 일반 비동기 처리처럼 바로 다음 코드를 실행하는 것이 아니라 결과값을 얻을 때까지 기다린다.
    • 따라서 일반적인 동기 코드와 동일한 흐름으로 코드를 작성할 수 있어 코드를 읽기도 쉬워진다.
  • 일반적으로 await의 대상이 되는 비동기 처리 코드는 프로미스를 반환하는 API 호출 함수이다.

예시

async function fetchAuthorName(postId) {
  const postResponse = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${postId}`
  );
  const post = await postResponse.json();
  const userId = post.userId;
  const userResponse = await fetch(
    `https://jsonplaceholder.typicode.com/users/${userId}`
  );
  const user = await userResponse.json();
  return user.name;
}

fetchAuthorName(1).then((name) => console.log("name:", name));
  • 주의할 점은 async 키워드가 붙어있는 함수에서 명시적으로 Promise 객체를 생성하여 리턴하지 않아도 Promise 객체가 리턴된다.
  • 위의 코드를 보면 fetchAuthorName 함수에서 user.name을 리턴하지만, 이 함수를 호출하면 then 메서드를 통해 리턴값을 얻어야 한다.

✨ 예외 처리

  • 동기/비동기 구분없이 try/catch로 일관되게 예외 처리를 할 수 있다.
async function fetchAuthorName(postId) {
  const postResponse = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${postId}`
  );
  const post = await postResponse.json();
  const userId = post.userId;

  try {
    const userResponse = await fetch(
      `https://jsonplaceholder.typicode.com/users/${userId}`
    );
    const user = await userResponse.json();
    return user.name;
  } catch (err) {
    console.log("Faile to fetch user:", err);
    return "Unknown";
  }
}

fetchAuthorName(1).then((name) => console.log("name:", name));

참고: [자바스크립트] 비동기 처리 3부 - async/await

post-custom-banner

0개의 댓글