前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库Promise.any AggregateError
JavaScript异步与 Promise

Promise.any 全部失败时会报什么错?每个失败原因怎么拿?

所有输入都失败时,Promise.any 以一个 AggregateError 拒绝。它是 Error 的子类,每个失败原因按输入顺序放在 err.errors 数组里,遍历这个数组就能拿到全部原因。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#异步与 Promise#异步编程
先看核心答案读代码示例
理解线索

一个错误装下所有错误

  1. Promise.any第一个成功就兑现,只有全部失败才拒绝
  2. AggregateError继承自 Error,专门用来打包多个错误
  3. errors 数组按输入顺序存放每个 Promise 的拒绝原因

errors 的顺序跟着输入走,不跟失败的先后走。第 0 项永远对应你传进去的第一个 Promise,哪怕它是最后一个失败的。

核心回答

先记住这个答案

Promise.any 只要有一个输入成功就兑现为那个值,只有全部失败时才拒绝。拒绝值是一个 AggregateError,它继承自 Error,多了一个 errors 属性,是一个数组,按输入顺序存着每个 Promise 的拒绝原因。所以在 catch 里先判断 err instanceof AggregateError,再遍历 err.errors,就能把每个失败原因都拿出来。

  • 全部失败才拒绝,拒绝值是 AggregateError
  • 失败原因在 err.errors,顺序和输入一致
  • 传空数组会立刻以 AggregateError 拒绝
  • 判断用 err instanceof AggregateError

三个节点全挂了会拿到什么

典型场景是多节点兜底:同一份数据有主节点、备用节点和 CDN 三个来源,谁先成功就用谁。如果三个都失败,就得告诉用户或者上报每个节点的失败原因。

读出每个失败原因JavaScript
const p1 = Promise.reject(new Error('主节点超时'))
const p2 = new Promise((_, reject) => setTimeout(() => reject(new Error('备用节点 502')), 100))
const p3 = Promise.reject('CDN 不可用') // 拒绝原因不一定是 Error 对象

Promise.any([p2, p1, p3]).catch((err) => {
  console.log(err instanceof AggregateError) // true
  console.log(err.name)
  console.log(err.errors.length)
  // p2 最后失败,但它排在第 0 位
  err.errors.forEach((e, i) => console.log(i, e instanceof Error ? e.message : e))
})
查看输出与解释
true
AggregateError
3
0 备用节点 502
1 主节点超时
2 CDN 不可用

p1 和 p3 立刻就失败了,p2 要等 100 毫秒才失败。Promise.any 会一直等到最后一个也失败才拒绝,所以这里的 catch 在 100 毫秒后才执行。 打印出来先是 p2,然后才是 p1 和 p3,也就是传进去的顺序,和谁先失败无关。这和 Promise.all 的结果数组是同一个规则:按位置对应,方便你知道第几个来源出了问题。

AggregateError 本身长什么样

AggregateError 是 ES2021 和 Promise.any 一起加进来的内置错误类型,专门用来表示「好几个错误打包成一个」。

它有哪些属性
name 固定是 'AggregateError'。message 由引擎生成,V8 里是 All promises were rejected,不要拿它做判断。errors 是真正有用的部分,里面的元素就是原样的拒绝原因:原来 reject 的是 Error 对象,这里就是 Error 对象;原来 reject 的是字符串,这里就是字符串。所以遍历时最好像上面代码一样兼容两种情况。 它也可以自己用 new 创建,写法是 new AggregateError([err1, err2], '批量上传失败'),第一个参数是错误列表,第二个是 message。自己写批量任务,需要把多个失败一起抛出去时,可以直接复用这个类型。
空数组是个特例
Promise.any([]) 没有任何输入可以成功,所以它会直接以 AggregateError 拒绝,errors 是空数组。这一点和 Promise.all([]) 正好相反,后者会立刻兑现为空数组。动态拼接请求列表时,如果列表可能为空,要先判断一下,别让用户看到一个莫名其妙的失败提示。
回答前,多想一步

容易答错的地方

以为有一个失败就会进 catch
那是 Promise.all 的行为。Promise.any 会忽略中间的失败,只要最后有一个成功,then 就能拿到值,那些失败原因不会出现在任何地方。只有全军覆没,才会进 catch。
以为 errors 按失败时间排序
errors 按输入位置排列。想知道哪个来源失败了,直接按下标对应原数组就行,不需要额外记录。
在 catch 里直接读 err.message 给用户看
AggregateError 的 message 是引擎写的笼统文案,看不出具体原因。要给用户或日志有用的信息,得去 err.errors 里取。
试着用自己的话回答

面试官还会怎么问?

catch 里怎么区分 AggregateError 和别的错误?

用 err instanceof AggregateError。Promise.any 自己只会以 AggregateError 拒绝,但如果你在它后面接了 then,then 回调里抛出的普通错误也会流到同一个 catch,所以判断一下类型更稳。

想要全部结果,不管成功失败,该用什么?

用 Promise.allSettled。它等所有输入都结束,返回一个数组,每项是 { status: 'fulfilled', value } 或 { status: 'rejected', reason },永远不会拒绝。Promise.any 适合「要一个成功的就够」,Promise.allSettled 适合「每个结果都要处理」。

老浏览器不支持 Promise.any 怎么办?

可以用 Promise.all 反过来实现:把每个 Promise 的成功和失败对调,成功变拒绝、失败变兑现,再交给 Promise.all。这样第一个成功会让 Promise.all 立刻拒绝,拿到的就是那个成功值;全部失败时 Promise.all 兑现,拿到的正好是按顺序排列的错误数组。

从一道题,走向一组知识

把知识连起来

异步与 Promise

Promise.any 和 Promise.race 都是取最快的,区别在哪?

知道 any 失败时怎么报错后,再对比 race。它遇到第一个失败就直接拒绝,不会等其他结果。

异步与 Promise

在 new Promise 的 executor 里直接 throw,Promise 会变成 rejected 吗?

errors 数组里装的就是各个 Promise 的拒绝原因,拒绝原因是 Error 还是字符串,取决于当初怎么 reject 的。

参考资料

  • JavaScript:异步与 Promise参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 三个节点全挂了会拿到什么
  3. AggregateError 本身长什么样
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑