JavaScript 비동기 처리, Promise에서 async/await로 전환
배경
프로젝트에서 API 호출 로직이 Promise 체이닝으로 복잡하게 얽혀있었다. 특히 여러 API를 순차적으로 호출하는 부분에서 .then()이 4~5단계로 중첩되어 가독성이 떨어졌다.
기존 코드
function getUserData(userId) {
return fetchUser(userId)
.then(user => {
return fetchUserPosts(user.id)
.then(posts => {
return fetchPostComments(posts[0].id)
.then(comments => {
return { user, posts, comments };
});
});
})
.catch(error => {
console.error('Error:', error);
throw error;
});
}
async/await로 전환
async function getUserData(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchUserPosts(user.id);
const comments = await fetchPostComments(posts[0].id);
return { user, posts, comments };
} catch (error) {
console.error('Error:', error);
throw error;
}
}
중첩이 사라지고 동기 코드처럼 읽힌다. try/catch로 에러 처리도 일관성있게 가능하다.
병렬 처리
순차 처리가 필요없는 경우 Promise.all을 함께 사용했다.
async function getMultipleUsers(userIds) {
try {
const users = await Promise.all(
userIds.map(id => fetchUser(id))
);
return users;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
주의사항
- forEach 내부에서 await 사용 불가 (for...of 사용)
- 에러 처리를 빼먹으면 unhandled rejection 발생
- Babel preset-env 설정 필요 (target 브라우저 확인)
결과
팀 내 코드 리뷰에서 가독성이 좋다는 피드백을 받았다. 신규 API 호출 로직은 모두 async/await로 작성하기로 컨벤션을 정했다.