Promise.all 默认任一reject即抛错,需try...catch捕获首个错误;Promise.allSettled始终resolve并返回各任务状态;可手动包装Promise实现不中断并发执行。

在 async 函数中处理 Promise.all 的错误,关键在于理解它“全成功才 resolve,任一 reject 就抛错”的默认行为,并主动用 try...catch 捕获,或改用更灵活的 Promise.allSettled。
用 try...catch 捕获 Promise.all 的第一个拒绝
Promise.all 遇到任意一个 Promise 被 reject,就会立即 reject,并把第一个出错的 reason 传给 catch。这意味着你无法直接拿到所有 Promise 的结果(包括成功的那些),只能拿到最先失败的那个错误。
- 适合场景:只要有一个失败就整体失败,比如批量创建资源且必须全部成功
- 写法示例:
try {
const results = await Promise.all([
fetch('/api/user/1'),
fetch('/api/user/2'),
fetch('/api/user/3')
]);
return results;
} catch (error) {
// 这里只捕获第一个失败的 fetch 错误
console.error('其中一个请求失败:', error);
throw error;
}
}
用 Promise.allSettled 获取每个 Promise 的最终状态
如果需要知道每个子任务是成功还是失败(不管有没有错误),应改用 Promise.allSettled。它总是 resolve,返回一个对象数组,每个对象含 status("fulfilled" 或 "rejected")和对应的 value 或 reason。
- 适合场景:容错批量操作,比如发通知、日志上报、数据同步
- 写法示例:
const promises = [
fetch('/api/log/1').then(r => r.json()),
fetch('/api/log/2').then(r => r.json()),
fetch('/api/log/3').then(r => r.json())
];
const results = await Promise.allSettled(promises);
const successes = results.filter(r => r.status === 'fulfilled').map(r => r.value);
const failures = results.filter(r => r.status === 'rejected').map(r => r.reason);
console.log('成功:', successes);
console.log('失败:', failures);
return { successes, failures };
}
手动包装 Promise 实现“不中断 + 分离结果”
若仍想用 Promise.all 但避免被中断,可提前把每个 Promise 包装成必定 resolve 的形式(例如返回 { data, error } 结构)。
- 常用技巧:用
.then(...).catch(...)或 IIFE 包裹单个 Promise - 示例:
return p
.then(data => ({ success: true, data }))
.catch(error => ({ success: false, error }));
}
async function batchSafe() {
const results = await Promise.all([
safe(fetch('/api/a')),
safe(fetch('/api/b')),
safe(fetch('/api/c'))
]);
const [a, b, c] = results;
if (!a.success) console.error('A failed:', a.error);
if (b.success) console.log('B ok:', b.data);
return results;
}
注意 await 和 Promise.all 的执行时机
await Promise.all([...]) 是等待整个数组并发执行完再继续;而 await 单个 Promise 是串行。别误写成 await p1; await p2; await p3;——这失去并发优势。
- 错误写法(串行):
await fetch(a); await fetch(b); await fetch(c); - 正确写法(并发):
await Promise.all([fetch(a), fetch(b), fetch(c)]); - 混合策略:先并发发起,再分别 await 处理(较少用,通常没必要)

















