Promise.allSettled 폴리필 구현하기

문제 상황

대시보드에서 5개의 독립적인 API를 동시에 호출하는데, 하나가 실패하면 Promise.all 특성상 전체가 reject되어 나머지 성공한 데이터도 사용할 수 없었다. 각 API는 독립적이므로 일부 실패해도 성공한 것들은 화면에 보여줘야 했다.

해결 방법

Promise.allSettled가 Stage 3 제안 단계라 아직 사용할 수 없어서 직접 구현했다.

function allSettled(promises) {
  return Promise.all(
    promises.map(promise =>
      Promise.resolve(promise)
        .then(value => ({ status: 'fulfilled', value }))
        .catch(reason => ({ status: 'rejected', reason }))
    )
  );
}

// 사용 예시
const apis = [
  fetch('/api/user'),
  fetch('/api/orders'),
  fetch('/api/stats'),
  fetch('/api/notifications'),
  fetch('/api/settings')
];

allSettled(apis).then(results => {
  results.forEach((result, index) => {
    if (result.status === 'fulfilled') {
      console.log(`API ${index} 성공:`, result.value);
    } else {
      console.error(`API ${index} 실패:`, result.reason);
    }
  });
});

핵심은 각 Promise를 catch로 감싸서 reject되지 않게 만드는 것이다. 모든 Promise가 항상 resolve되므로 Promise.all을 안전하게 사용할 수 있다.

결과

일부 API가 실패해도 페이지가 정상적으로 렌더링되고, 실패한 섹션만 에러 메시지를 보여줄 수 있게 되었다. 유저 경험이 확실히 개선되었다.

나중에 브라우저 지원이 되면 네이티브 구현으로 교체할 예정이다.