ES6 Promise.all과 Promise.race 실무 활용
문제 상황
대시보드 화면에서 사용자 정보, 통계 데이터, 알림 목록을 각각 다른 API에서 가져와야 했다. 처음엔 순차적으로 호출했는데 로딩 시간이 너무 길었다.
const user = await fetchUser();
const stats = await fetchStats();
const notifications = await fetchNotifications();
// 총 3초 이상 소요
Promise.all 적용
세 API가 서로 의존성이 없어서 병렬 처리가 가능했다.
const [user, stats, notifications] = await Promise.all([
fetchUser(),
fetchStats(),
fetchNotifications()
]);
// 가장 느린 API 기준 1.2초로 단축
단, Promise.all은 하나라도 reject되면 전체가 실패한다는 점을 주의해야 했다. 알림 API 장애로 전체 화면이 에러 나는 이슈가 있었다.
부분 실패 허용
필수 데이터와 선택 데이터를 구분해서 처리했다.
const [user, stats] = await Promise.all([
fetchUser(),
fetchStats()
]);
const notifications = await fetchNotifications()
.catch(err => {
console.error('알림 로드 실패:', err);
return [];
});
Promise.race 활용
API 타임아웃 처리에 Promise.race를 사용했다.
const timeout = (ms) => new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), ms)
);
const data = await Promise.race([
fetchData(),
timeout(5000)
]);
첫 번째 완료되는 Promise만 결과로 받기 때문에 타임아웃 로직을 깔끔하게 구현할 수 있었다.
정리
- Promise.all: 모든 결과 필요, 하나라도 실패시 전체 실패
- Promise.race: 가장 빠른 결과만 필요
- 부분 실패 허용이 필요하면 catch로 개별 처리
ES6 Promise API를 제대로 활용하니 비동기 처리가 훨씬 명확해졌다.