Promise.allSettled vs Promise.all:部分的な失敗を適切に処理する
問題
ダッシュボードで複数のAPIを同時に呼び出す必要がありました。Promise.allを使ったところ、1つでも失敗すると全体がrejectされ、成功したデータまで失われてしまいました。
// 1つでも失敗すると全部失われる
try {
const [users, orders, stats] = await Promise.all([
fetchUsers(),
fetchOrders(), // これが失敗すると
fetchStats(),
]);
} catch (err) {
// users, statsの結果も使えない
}
解決方法
Promise.allSettledを使えば、すべてのPromiseが完了するまで待ち、それぞれの成功・失敗を個別に確認できます。
const results = await Promise.allSettled([
fetchUsers(),
fetchOrders(),
fetchStats(),
]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`API ${index} 成功:`, result.value);
} else {
console.log(`API ${index} 失敗:`, result.reason);
}
});
実務では以下のようなパターンで使います:
const [usersResult, ordersResult, statsResult] = await Promise.allSettled([
fetchUsers(),
fetchOrders(),
fetchStats(),
]);
const dashboard = {
users: usersResult.status === 'fulfilled' ? usersResult.value : [],
orders: ordersResult.status === 'fulfilled' ? ordersResult.value : [],
stats: statsResult.status === 'fulfilled' ? statsResult.value : null,
};
// 失敗したものだけログ出力
const failures = [usersResult, ordersResult, statsResult]
.filter(r => r.status === 'rejected');
if (failures.length > 0) {
console.error('一部のAPIが失敗:', failures.map(f => f.reason));
}
ポイント
Promise.allは1つでも失敗すると即座にreject — すべて成功が必須の場合に使いますPromise.allSettledはすべて完了後に個別の結果を返します — 部分的な失敗を許容する場合に使います- ダッシュボードやバッチ処理など「成功した分は表示し、失敗した分は別途処理」するシナリオに最適です