JavaScript Promise.any 怎样获取第一个成功结果
当页面需要从多个接口、缓存层或备用资源中先拿到一个可用结果时,Promise.any() 是最直接的选择:它等待输入中第一个 fulfilled 的 Promise,并把那个成功值交给调用方;先 reject 的候选不会让整体立即失败。要注意,所有候选都失败时才会进入 AggregateError,而已经发出的其他任务也不会因为某个结果先返回就自动取消。
Promise.any()看的是“第一个成功完成”,不是数组中的第一个元素。- 全部失败或传入空 iterable 时,捕获
AggregateError,用errors定位原因。 - 它与
Promise.race()、Promise.all()的成功条件不同,也不负责取消剩余请求。
const value = await Promise.any(candidates)就能拿到第一个 fulfilled 值;若没有任何候选成功,再在catch中处理AggregateError。
把候选请求交给 Promise.any
调用方式是把一组 Promise 或 thenable 放入 iterable。数组位置只决定输入顺序,不决定哪个值获胜;真正决定结果的是哪个 Promise 先 fulfilled。下面用三个延迟不同的候选模拟多源读取:
function delayedValue(value, delay, shouldFail = false) {
return new Promise((resolve, reject) => {
// 用延迟模拟不同数据源的响应速度,失败候选只影响自己的状态。
setTimeout(() => {
if (shouldFail) {
reject(new Error(`${value} 暂不可用`));
return;
}
resolve(value);
}, delay);
});
}
async function pickFirstSuccess() {
const candidates = [
delayedValue("主接口", 180, true),
delayedValue("边缘缓存", 80),
delayedValue("备用接口", 240),
];
try {
// Promise.any 只接收首个 fulfilled 值,不等待数组中的所有成功结果。
const value = await Promise.any(candidates);
return value;
} catch (error) {
// 只有全部候选失败时才会走这里;保留原始错误供上层记录。
throw error;
}
}
pickFirstSuccess().then((value) => {
console.log(value); // 边缘缓存
});
这个例子里“主接口”先失败,“边缘缓存”随后成功,所以结果是“边缘缓存”。即使“备用接口”仍在等待,组合 Promise 也已经 fulfilled。真实项目中可以把 fetch()、缓存读取函数或其他异步封装直接放进 candidates,但要保证每个候选在失败时真正 reject,而不是用一个错误对象 fulfilled,否则它会被当成成功值。

全部失败时用 AggregateError 找原因
如果所有输入都 reject,Promise.any() 才会拒绝。捕获对象是 AggregateError,其中的 errors 数组按传入 Promise 的顺序保存原因,而不是按实际完成的先后排列。这个特性适合把每个来源的失败信息映射回来源名称:
async function readFromFallbacks() {
const names = ["主接口", "边缘缓存", "备用接口"];
const candidates = names.map((name, index) => {
return Promise.reject(new Error(`${name} 返回失败码 ${500 + index}`));
});
try {
// 三个输入全部 reject,Promise.any 才会抛出 AggregateError。
return await Promise.any(candidates);
} catch (error) {
if (error instanceof AggregateError) {
// errors 与 names 同序,可稳定生成逐来源的诊断信息。
return error.errors.map((reason, index) => ({
source: names[index],
message: reason.message,
}));
}
throw error;
}
}
不要只把 AggregateError 转成一句“全部失败”。生产日志至少应保留来源名和错误原因;如果传入空数组,也会走失败分支,因此在构造候选列表前可以先判断是否为空,并给调用方一个更明确的业务提示。

Promise.any、Promise.race 与 Promise.all 怎么选
| 组合器 | 何时结束 | 结果语义 | 常见用途 |
|---|---|---|---|
Promise.any | 首个 fulfilled,或全部 reject | 一个成功值;全失败为 AggregateError | 多源兜底、先可用资源 |
Promise.race | 首个 settled | 第一个成功或失败都决定结果 | 超时竞争、首个状态 |
Promise.all | 全部 fulfilled,或一个 reject | 按输入顺序返回全部成功值 | 必须齐全的并行任务 |
如果“第一个返回的结果”可能是失败,选 race;如果必须拿齐所有数据,选 all。如果只关心任意一个成功来源,才用 any。另外,any fulfilled 后,剩余请求仍可能消耗网络和服务端资源,需要取消时要把 AbortController 设计进每个候选任务,并在业务层决定何时调用 abort()。
常见问题
Promise.any 会返回数组中第一个 Promise 吗?
不会。数组位置只用于建立输入顺序;返回的是运行过程中第一个 fulfilled 的值。
有一个 Promise reject 会导致 Promise.any 失败吗?
不会。只要仍有候选最终 fulfilled,先发生的 reject 就会被忽略;只有全部候选 reject 才失败。
Promise.any 成功后会自动停止其他请求吗?
不会。它只结束组合结果,不会取消底层操作;需要节省资源时应额外设计取消信号。
CSS prefers-reduced-motion 怎样关闭非必要动画
- 上一篇
- CSS prefers-reduced-motion 怎样关闭非必要动画
- 下一篇
- JavaScript queueMicrotask 怎样安排微任务执行顺序
-
- 文章 · 前端 | 57分钟前 |
- Vite import.meta.env 怎样区分构建期和运行期变量
- 260浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- URLSearchParams 怎样删除指定键的全部参数值
- 118浏览 收藏
-
- 文章 · 前端 | 1小时前 | websocket close CloseEvent 异常断开
- WebSocket close 事件怎样区分主动与异常断开
- 410浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- ReadableStream.getReader 怎样逐块读取上传数据
- 202浏览 收藏
-
- 文章 · 前端 | 1小时前 | Fetch AbortController AbortSignal fetch取消请求 Request.signal
- Fetch Request.signal 怎样取消已经发出的请求
- 300浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JavaScript queueMicrotask 怎样安排微任务执行顺序
- 209浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS prefers-reduced-motion 怎样关闭非必要动画
- 211浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS :has 怎样根据子元素状态选择父元素
- 446浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端开发 · CSS 响应式布局 object-fit aspect-ratio 媒体卡片
- CSS aspect-ratio 怎样稳定媒体卡片比例
- 498浏览 收藏
-
- 文章 · 前端 | 13小时前 | CSS animation transform 前端动画 animation-composition
- CSS animation-composition 怎样叠加多个动画效果
- 221浏览 收藏
-
- 文章 · 前端 | 20小时前 |
- Vite import.meta.glob 怎样批量加载模块
- 157浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 720次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 727次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 804次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 764次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 602次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 智能体安全引领产业升级——国内AI安全产品市场深度分析
- 2026-08-21 501浏览
-
- CSS变量简化按钮悬停效果技巧
- 2026-05-31 501浏览
-
- JavaScript符号类型详解与应用
- 2026-05-31 501浏览
-
- HTML剪贴板复制粘贴怎么用
- 2026-05-26 501浏览

