promise.allsettled 是推荐方案,它等待所有 promise 结束并返回每个的完整状态(fulfilled/rejected)及对应值或原因,无需手动兜底;旧环境可回退到用 .catch() 包装再 promise.all 的方式。

Promise.all 默认遇到任意一项失败就立即 reject,不会等待其他 Promise 完成。若想“不管谁失败,都等所有 Promise 结束,并拿到所有成功结果”,不能直接用 Promise.all,而要先让每个 Promise 都变成“永远不会拒绝”的状态(即兜底处理错误),再统一收集结果。
把每个 Promise 包一层,转为 always-resolve
核心思路:对数组中每个 Promise,用 .catch() 捕获错误,返回一个包含状态和值的对象(比如 { ok: true, data } 或 { ok: false, error }),确保它一定 resolve。
示例写法:
const promises = [
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
];
// 改造成每个都 resolve 的版本
const safePromises = promises.map(p =>
p
.then(data => ({ ok: true, data }))
.catch(error => ({ ok: false, error }))
);
Promise.all(safePromises).then(results => {
const successes = results.filter(r => r.ok).map(r => r.data);
const failures = results.filter(r => !r.ok).map(r => r.error);
console.log('成功项:', successes);
console.log('失败项:', failures);
});
用 Promise.allSettled(推荐,现代方案)
ES2020 引入了 Promise.allSettled,原生支持“等全部结束、不因失败中断”,返回每个 Promise 的完整状态(fulfilled 或 rejected)及对应值或原因。
它更简洁、语义更清晰,且无需手动包装:
Promise.allSettled(promises).then(results => {
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);
});
注意点与常见误区
Promise.allSettled 是标准方法,但需注意浏览器/运行时兼容性:Chrome 76+、Firefox 74+、Node.js 12.9+ 已支持;旧环境需 polyfill 或回退到手动包装方案。
不要混用 Promise.all 和 try/catch:在 async/await 中对 Promise.all 加 try/catch 只能捕获整体 reject,仍拿不到已 resolve 的那些结果 —— 因为一旦有失败,Promise.all 就立刻终止,其余仍在 pending 的 Promise 不会自动取消,但你无法从 reject 值里提取部分成功数据。
如果需要“失败不阻断 + 自动重试 + 聚合结果”,可封装工具函数,例如:
- 给每个 Promise 加上重试逻辑(如用
retry(() => fetch(...))) - 统一用 allSettled 收集,再按需过滤、映射、降级(如失败时用默认值替代)
本质上,关键不是“绕过失败”,而是主动管理每个异步任务的状态边界。用 allSettled 或手动兜底,都是把“异常”转化为“可结构化处理的数据”,这才是可控并发的正确姿势。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











