Promise.any 返回第一个成功完成的 Promise 的值,适用于多服务器探测等场景;所有请求失败时抛出包含全部错误的 AggregateError。

Promise.any 会等待所有 Promise 中**第一个成功完成**的(即 fulfilled 状态),并立即返回它的值;只要有一个成功,就立刻 resolve,其余失败或仍在进行中的 Promise 不影响结果。它特别适合“多服务器探测”场景:向多个服务器同时发请求,取最快响应且成功的那个。
基本用法:并发请求多个 URL
假设你有三个备用 API 地址,想选最先返回有效数据的服务器:
const urls = [
'https://server-a.example.com/health',
'https://server-b.example.com/health',
'https://server-c.example.com/health'
];
const promises = urls.map(url =>
fetch(url)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
// ⚠️ 注意:Promise.any 会忽略 rejected 的 Promise
// 所以这里必须抛错,让失败的请求变成 rejected
throw new Error(`Failed on ${url}: ${err.message}`);
})
);
Promise.any(promises)
.then(result => console.log('✅ 最快可用服务器返回:', result))
.catch(err => console.error('❌ 所有服务器都不可用:', err.errors));
关键细节:如何让失败请求“不阻塞”但又可识别
Promise.any 只关心 fulfilled,自动忽略 rejected —— 所以你不需要手动包装成 Promise.resolve() 来“吞掉错误”。但要注意:
- 每个 fetch 必须在业务逻辑失败时 显式 throw(比如 HTTP 非 2xx、JSON 解析失败),否则会被当成成功,导致误判
- 如果所有请求都 rejected,Promise.any 会 reject 一个 AggregateError,其
errors属性包含所有失败原因 - 不支持取消已发起的请求(需配合 AbortController 实现超时控制)
增强实用性:加超时 + 优先级标记
真实场景中,你还希望防止单个慢请求拖累整体(比如某服务器卡死)。可以结合 AbortController 和封装函数:
立即学习“Java免费学习笔记(深入)”;
function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
return fetch(url, { signal: controller.signal })
.then(res => {
clearTimeout(id);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
clearTimeout(id);
throw new Error(`Timeout or error on ${url}: ${err.message}`);
});
}
// 使用
Promise.any([
fetchWithTimeout('https://a.com/api', 3000),
fetchWithTimeout('https://b.com/api', 3000),
fetchWithTimeout('https://c.com/api', 3000)
])
.then(data => console.log('✅ 用时最短且成功的响应:', data))
.catch(e => {
if (e instanceof AggregateError) {
console.warn('⚠️ 全部失败,原因:', e.errors.map(x => x.message));
}
});
兼容性提醒
Promise.any 是 ES2021 新特性,现代浏览器和 Node.js 16+ 原生支持。若需兼容旧环境:
- Node.js core-js /
es6-promisepolyfill - 浏览器:检查 caniuse,必要时用
Promise.race+ 手动过滤失败项(但逻辑更重)


















