Promise.all 一错即停,适合强一致性场景;Promise.allSettled 则全部返回结果,含 status、value 或 reason,适用于需汇总、降级或统计的业务。

Promise.all 和 Promise.allSettled 都能并发执行多个 Promise,但容错逻辑完全不同:Promise.all 一错即停,适合强一致性场景;Promise.allSettled 则“来者不拒”,所有请求无论成败都返回结果,更适合需要汇总、降级或统计的业务。
用 Promise.allSettled 处理部分失败的聚合请求
当你要同时拉取用户信息、订单列表和通知数,但允许某一项失败(比如通知服务临时不可用),就不能用 Promise.all —— 它一旦有一个 reject,整个就中断,其余结果全丢。Promise.allSettled 则始终返回一个数组,每个元素包含 status("fulfilled" 或 "rejected")和对应的 value 或 reason。
示例:
const [userRes, orderRes, noticeRes] = await Promise.allSettled([
fetch('/api/user'),
fetch('/api/orders'),
fetch('/api/notifications')
]);
const userData = userRes.status === 'fulfilled' ? await userRes.value.json() : null;
const orderData = orderRes.status === 'fulfilled' ? await orderRes.value.json() : [];
const noticeCount = noticeRes.status === 'fulfilled'
? (await noticeRes.value.json()).count
: 0;
这样即使通知接口超时,用户和订单数据仍可正常渲染,UI 不卡死,体验更稳。
用 Promise.all 做原子性校验或关键链路
Promise.all 的“全成功才继续”特性,正好用于必须全部就绪才能推进的场景,比如表单提交前并行校验多个字段(手机号格式、验证码有效性、用户名是否可用),任一校验失败就中止提交,避免无效请求。
操作建议:
- 把每个校验封装成返回 Promise 的函数,resolve 表示通过,reject 表示失败并带错误信息
- 用 Promise.all 聚合后统一处理:成功则调用主提交逻辑;catch 捕获第一个失败项,提取其 error.message 展示给用户
- 注意不要在各校验中吞掉错误(比如 try/catch 后 return null),否则 Promise.all 无法感知失败
混合使用:先 allSettled 收集,再 all 校验关键子集
实际项目中常需分层容错。例如加载仪表盘:头像、昵称、权限列表是核心(缺一不可),而天气、待办、新闻是锦上添花。可先用 allSettled 并发拉取全部,再对核心三项单独做 all 校验。
做法:
- 发起 allSettled 获取全部响应
- 从结果中筛选出核心项(如 status !== 'fulfilled' 的就标记为缺失)
- 若核心项有失败,可抛出业务错误(如 throw new Error('用户基础信息加载失败')),触发兜底页或重试逻辑
- 非核心项直接降级(显示默认值、占位图或隐藏模块)
注意点:避免无意义的并发与内存泄漏
并发不是越多越好。过多请求可能触发浏览器限制(通常 6~10 个同域并发)、服务端限流或客户端内存压力。
建议:
- 对大量相似请求(如批量查 100 个商品价格),考虑分组节流,每组 5~10 个用 allSettled 并发,组间串行或加 delay
- 所有 Promise 实例应有明确生命周期,避免在组件卸载后还 resolve(尤其 React 中),可用 AbortController 或 isMounted 标记规避
- allSettled 返回的结果数组顺序严格对应输入顺序,别依赖索引之外的标识,必要时在请求外层包一层 { id, promise } 结构











