これは「非同期処理を複数まとめて実行しつつ、一部が失敗しても全体を止めずに進める」という実践的なテーマです。
API連携やWebアプリで「部分的にデータ取得に失敗しても、取れる部分だけ表示したい」という場面で頻出します。
目標
複数の
fetch(非同期処理)を並列で実行し、
一部が失敗してもプログラム全体を落とさず、成功した部分だけ処理を続ける。
基本の考え方
非同期処理をまとめて待つには:
await Promise.all([...])
JavaScriptを使うのが基本ですが、
👉 ひとつでも失敗(reject)すると全体がエラーになる のが難点。
そこで、落ちないようにするために:
Promise.allSettled()(すべての結果を「成功」「失敗」両方とも返す)- 各処理を
try...catchでラップする
…という工夫をします。
❌ 悪い例:Promise.all() だけで並列実行
async function fetchDataBad() {
try {
const results = await Promise.all([
fetch('https://example.com/api/user'), // OK
fetch('https://wrong.url/api/posts'), // ❌ ここで失敗
fetch('https://example.com/api/comments') // OK
]);
// ここには到達しない(1つでも失敗すると全体がreject)
const jsons = await Promise.all(results.map(r => r.json()));
console.log('全データ:', jsons);
} catch (err) {
console.error('どれか1つでも失敗 → 全体エラー:', err.message);
}
}
fetchDataBad();
JavaScript問題点
- 2番目のAPIが落ちた瞬間、残りもすべて中断される。
- 成功していたデータも取得できない。
✅ 良い例:Promise.allSettled() を使う
async function fetchDataGood() {
const urls = [
'https://example.com/api/user',
'https://wrong.url/api/posts', // ここは失敗
'https://example.com/api/comments'
];
const results = await Promise.allSettled(
urls.map(url => fetch(url))
);
const successes = [];
const failures = [];
for (const [index, result] of results.entries()) {
if (result.status === 'fulfilled') {
successes.push(await result.value.json());
} else {
failures.push({ url: urls[index], error: result.reason });
}
}
console.log('✅ 成功データ:', successes);
console.log('⚠️ 失敗データ:', failures);
}
fetchDataGood();
JavaScript出力イメージ
✅ 成功データ: [ {name:"Alice"}, {comment:"OK"} ]
⚠️ 失敗データ: [ {url:"https://wrong.url/api/posts", error: TypeError: ...} ]
ポイント
- どれが成功/失敗かを「個別」に判定できる
- 全体が止まらない
- 成功した分だけで処理を進められる
応用版:個々の fetch に try…catch を仕込む
もう少し丁寧に「中身で安全に処理」する書き方もあります。
async function safeFetch(url) {
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (e) {
return { error: true, message: e.message, url };
}
}
async function fetchAllData() {
const urls = [
'https://example.com/api/user',
'https://wrong.url/api/posts',
'https://example.com/api/comments'
];
const promises = urls.map(u => safeFetch(u));
const results = await Promise.all(promises);
const ok = results.filter(r => !r.error);
const ng = results.filter(r => r.error);
console.log('✅ 成功データ:', ok);
console.log('⚠️ 失敗データ:', ng);
}
fetchAllData();
JavaScriptメリット
- 1つの処理失敗で全体が止まらない
- 成功・失敗をわかりやすく仕分けできる
Promise.allSettled()より柔軟に再利用できる
比較まとめ表
| 方法 | 特徴 | 向いているケース |
|---|---|---|
Promise.all() | 1つでも失敗すると全体エラー | 全部のAPIが成功しないと意味がない場合 |
Promise.allSettled() | 成功・失敗を両方返す | できるだけ多くの結果を集めたいとき |
個別 try...catch | 柔軟に再利用できる、安全 | 安定動作を最優先したいとき |
実務でのコツ
- 重要なデータ(例:ユーザー情報)は失敗したら再試行、
サブデータ(例:コメント数)は失敗してもスルーなど、優先度を分ける。 - 成功・失敗ログをわかりやすく残しておく。
- 大量のリクエストを同時に投げすぎない(API制限注意)。
まとめ(初心者が押さえるべきポイント)
| 覚えるべきこと | 説明 |
|---|---|
Promise.all() は「全成功前提」 | 1つでも落ちると全部落ちる |
Promise.allSettled() は「全結果を返す」 | 一部失敗でもOK |
個別 try...catch or safeFetch 関数 | 再利用・安全性重視 |
| 「一部成功でも続行する」設計 | 実務で超重要 |

