Promise.all 默认遇拒即止,需用 .catch 包装或 Promise.allSettled 获取全量结果;后者返回含 status/value/reason 的数组,更简洁可靠。

Promise.all 默认遇到任意一个 Promise 拒绝(reject)就会立即终止,整个调用返回失败。如果想让所有请求都执行完、即使部分失败也拿到全部结果(包括成功和失败信息),不能直接依赖 Promise.all 的默认行为,而要主动把每个 Promise “兜底”成一定成功的状态。
把每个 Promise 包装成“永不拒绝”的形式
核心思路是:对每个异步操作单独捕获错误,统一返回一个包含状态标记的对象(比如 { success: true, data } 或 { success: false, error })。这样 Promise.all 就不会中断,最终得到的是一个确定长度的结果数组。
常用写法是用 .catch() 捕获错误,并返回标准化结构:
const requests = [
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
];
// 改造成每个都 resolve 的版本
const safeRequests = requests.map(p =>
p.then(data => ({ success: true, data }))
.catch(error => ({ success: false, error }))
);
Promise.all(safeRequests).then(results => {
results.forEach((res, i) => {
if (res.success) {
console.log(`请求 ${i} 成功:`, res.data);
} else {
console.warn(`请求 ${i} 失败:`, res.error);
}
});
});
使用 Promise.allSettled(推荐,现代方案)
ES2020 引入了 Promise.allSettled,它天然支持“等所有 Promise 结束,不管成功或失败”,并返回每个 Promise 的完整状态对象({ status: 'fulfilled' | 'rejected', value | reason })。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
相比手动包装,更简洁、语义清晰、无需额外封装:
Promise.allSettled([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
]).then(results => {
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
console.log(`请求 ${i} 成功:`, result.value);
} else {
console.warn(`请求 ${i} 失败:`, result.reason);
}
});
});
注意:Promise.allSettled 在 Node.js 12.9+ 和主流浏览器中已原生支持;旧环境可用 polyfill 补齐。
按需分离成功与失败结果
拿到 allSettled 或手动包装后的结果后,常需分别提取成功数据和错误列表。可以简单用数组方法拆分:
-
提取所有成功响应的数据:
results.filter(r => r.status === 'fulfilled').map(r => r.value) -
提取所有失败原因:
results.filter(r => r.status === 'rejected').map(r => r.reason) - 若用自定义包装格式(
{ success, data, error }),对应改为filter(r => r.success)和filter(r => !r.success)
补充:需要“至少一个成功”时怎么办?
有时业务要求“只要有一个请求成功即可继续”,这不属于 Promise.all 或 allSettled 的范畴。可改用 Promise.race,或手动用 Promise.allSettled + 判断逻辑:
- 用
Promise.race获取首个完成(无论成败)的结果,再判断是否成功 - 更稳妥的做法:用
allSettled获取全部结果,然后检查是否有fulfilled项,再取第一个有效值
例如:
Promise.allSettled(promises).then(results => {
const fulfilled = results.find(r => r.status === 'fulfilled');
if (fulfilled) {
return fulfilled.value; // 返回第一个成功结果
}
throw new Error('所有请求均失败');
});

















