使用 Promise.allSettled 替代 axios.all,可确保所有请求无论成功或失败均返回结果,从而安全筛选出状态码非 200 的响应,避免因单个请求失败导致整个 Promise 链被 catch 中断。
使用 `promise.allsettled` 替代 `axios.all`,可确保所有请求无论成功或失败均返回结果,从而安全筛选出状态码非 200 的响应,避免因单个请求失败导致整个 promise 链被 `catch` 中断。
在使用 Axios 发起多个并发请求(如 axios.get)时,若任一请求返回非 200 状态码(例如 404、500),默认行为是触发 axios 的错误拦截机制——即整个 Promise.all(或旧版 axios.all)被拒绝,直接进入 catch 块,导致你无法访问其他成功响应的数据。这与 fetch 的默认“不自动 reject”行为不同,因此需要显式适配。
正确做法是绕过 Axios 自动抛错逻辑,改用原生 Promise.allSettled,它会等待所有 Promise 完成(无论 fulfilled 或 rejected),并统一返回包含 { status: 'fulfilled' | 'rejected', value | reason } 的结果数组。再结合 Axios 请求配置禁用自动错误抛出,即可实现精细化响应处理。
✅ 推荐实现(含错误抑制):
// 关键:设置 validateStatus 返回 true,阻止 axios 自动 reject 非 200 响应
const requests = urls.map(url =>
axios.get(url, {
validateStatus: () => true // 允许所有 HTTP 状态码进入 fulfilled 分支
})
);
const results = await Promise.allSettled(requests);
const successfulResponses = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value); // r.value 是完整的 AxiosResponse 对象
const failedPromises = results
.filter(r => r.status === 'rejected')
.map(r => r.reason); // r.reason 是被 reject 的 Error 实例(含网络/超时/取消等)
// 进一步按 HTTP 状态码分类(可选)
const httpErrors = successfulResponses.filter(res => res.status = 300);
const okResponses = successfulResponses.filter(res => res.status === 200);
⚠️ 注意事项:
- validateStatus: () => true 是关键,否则即使使用 allSettled,Axios 仍会在非 200 时主动 reject Promise,导致该请求落入 rejected 分支,但此时 reason 是 AxiosError,不包含响应体(需通过 error.response 访问);
- 若需保留原始响应数据(如 404 的响应体),建议统一走 fulfilled 分支,并在后续按 response.status 判断业务逻辑;
- Promise.allSettled 是 ES2020 标准,现代浏览器及 Node.js ≥ 12.9 均支持;旧环境可用 promise-all-settled polyfill;
- 不要混用 axios.all(已废弃)和 Promise.allSettled——前者本质仍是 Promise.all,无法解决本问题。
总结:通过 Promise.allSettled + validateStatus: () => true 组合,你既能保持并发效率,又能完全掌控每个请求的结果状态,实现真正意义上的“过滤而非中断”,是构建健壮批量请求逻辑的推荐实践。











