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))
메소드 체이닝을 통해서 then을 연쇄적으로 사용한다. then이 많아질 경우 에러가 발생했을 때 몇번째 then
에서 에러가 발생한 것인지 알기 어렵다.
promise를 사용하면 catch
메서드를 사용하여 예외 처리를 해야한다. 동기 코드와 비동기 코드가 섞여 있을 경우 예외 처리가 난해해지거나 예외 처리를 누락하는 경우가 생기기 쉽다.
then
메서드의 인자로 넘기는 콜백 함수 내에서 조건문이나 반복문을 사용하거나 여러 개의 Promise를 병렬로 또는 중첩해서 호출하는 경우 다단계 들여쓰기를 해야할 확률이 높아지고 코드 가독성이 떨어진다.
위의 문제들을 해결하기위해 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
를 추가한다.
await
는 async
가 붙어있는 함수 내부에서만 사용할 수 있다. 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))