[JavaScript] async / await

Hyein Son·2020년 9월 6일
0

JavaScript

목록 보기
7/10

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이 많아질 경우 에러가 발생했을 때 몇번째 then에서 에러가 발생한 것인지 알기 어렵다.

2. 예외 처리

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

3. 들여쓰기

then 메서드의 인자로 넘기는 콜백 함수 내에서 조건문이나 반복문을 사용하거나 여러 개의 Promise를 병렬로 또는 중첩해서 호출하는 경우 다단계 들여쓰기를 해야할 확률이 높아지고 코드 가독성이 떨어진다.


async / await

위의 문제들을 해결하기위해 es7에서는 async / await를 도입했다. 이를 사용하면 비동기적인 코드를 동기적인 코드로 보이게 작성할 수 있다.

async await를 사용하여 다시 작성하면 다음과 같다.

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
}

// async가 붙어있는 함수 호출 >>> Promise 객체 반환
fetchAuthorName(1).then((name) => console.log("name:", name))

function 앞에 async를 붙이고 내부에 Promise를 리턴하는 모든 비동기 함수 호출하는 부분 앞에는 await를 추가한다.

awaitasync가 붙어있는 함수 내부에서만 사용할 수 있다. await는 일반 비동기 처리처럼 바로 다음 줄로 넘어가지 않고 결과값을 얻을 때까지 기다려준다. 따라서 일반적인 동기 코드 처리와 같이 함수 호출 후 결과값을 변수에 할당하는 식으로 코드를 작성할 수 있고 읽기에도 수월해진다.

async가 붙어 있는 함수를 호출하면 Promise 객체가 자동으로 리턴된다. 따라서 then을 통해서 결과값을 출력할 수 있다. 하지만 만약 또 다른 async 키워드가 붙어있는 함수의 내부에서 async가 붙은 함수를 호출하게 되면 await를 사용해 동기적으로 보이도록 코드를 작성할 수 있다.

예외 처리

async / await를 사용하면 동기/비동기 구분없이 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))

참고
async / await

0개의 댓글