Promise.allSettled 是并发请求中保留每个请求完整状态的最佳选择,它不中断其余请求、不丢弃错误细节,返回含 status、value 或 reason 的数组,严格按输入顺序映射结果。

Promise.allSettled 是处理并发请求时保留每个请求完整状态(成功或失败)的最佳选择,它不会因某个请求失败而中断其余请求,也不会丢弃错误细节。
为什么不用 Promise.all 或 Promise.race
Promise.all 一旦有任意一个 Promise 被 reject,就立即 reject,其余结果全丢失;Promise.race 只返回第一个 settled 的结果,完全无法覆盖“全部执行+分别处理”的需求。而 allSettled 返回一个数组,每个元素都明确标记 status('fulfilled' 或 'rejected'),并附带 value 或 reason,天然适配需要逐个分析响应的场景。
基础用法:拿到每个请求的原始状态和数据
将所有接口 Promise 包装进数组,传给 allSettled,然后遍历结果判断状态:
const requests = [
fetch('/api/user'),
fetch('/api/orders'),
fetch('/api/settings')
];
Promise.allSettled(requests)
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`请求 ${index} 成功`, result.value);
} else {
console.error(`请求 ${index} 失败`, result.reason);
}
});
});
结合 await 和解构,让逻辑更清晰
配合 async/await 可读性更高,还能自然处理 JSON 解析等后续步骤(注意:fetch 成功不代表 HTTP 状态码是 2xx,需手动检查):
const apiCalls = [
fetch('/api/user').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
];
const results = await Promise.allSettled(apiCalls);
results.forEach((res, i) => {
if (res.status === 'fulfilled') {
console.log(`✅ 接口 ${i} 数据:`, res.value);
} else {
console.warn(`❌ 接口 ${i} 异常:`, res.reason.message || res.reason);
}
});
实际项目中的关键细节
- HTTP 错误不等于 Promise reject:fetch 在网络异常时才 reject,404/500 仍算 fulfilled,记得检查 response.ok 或 status
- 超时控制需额外封装:allSettled 本身不支持 timeout,可用 AbortController 或包装成带 timeout 的 Promise
- 避免未处理的 rejected Promise:如果某请求内部抛出未捕获错误(如 JSON 解析失败),它会变成 rejected 状态,reason 就是那个 error,可直接读取 message、stack 等
- 结果顺序严格对应入参顺序:第 0 个结果永远对应数组中第 0 个 Promise,适合做索引映射或批量更新 UI











