如何让 Axios 并行请求中过滤非 200 响应且不停整个流程?
- 内容介绍
- 文章标签
- 相关推荐
本文共计703个文字,预计阅读时间需要3分钟。
相关专题
使用 `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 < 200 || 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 组合,你既能保持并发效率,又能完全掌控每个请求的结果状态,实现真正意义上的“过滤而非中断”,是构建健壮批量请求逻辑的推荐实践。
本文共计703个文字,预计阅读时间需要3分钟。
相关专题
使用 `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 < 200 || 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 组合,你既能保持并发效率,又能完全掌控每个请求的结果状态,实现真正意义上的“过滤而非中断”,是构建健壮批量请求逻辑的推荐实践。

