promise.race 返回第一个 settled 的 promise 结果,无论 fulfilled 或 rejected;若首个 settled 为 reject 则整体拒绝,常用于超时控制,但不取消原始 promise。

Promise.race 会返回第一个 settled(即 fulfilled 或 rejected)的 Promise 的结果,而不是只取 fulfilled 的那个。也就是说,只要任意一个 Promise 完成(无论成功或失败),race 就立刻结束并返回它的结果。
它不区分成功与失败,谁先“定下来”就用谁
这是最关键的一点:Promise.race 不是“取最快成功的”,而是“取最先结束的”。如果第一个完成的是 reject,整个 race 就会以该 rejection 拒绝,不会等其他 Promise 成功。
- ✅ 如果 Promise A 在 100ms 后 resolve("A"),Promise B 在 200ms 后 resolve("B") → race 返回 "A"
- ❌ 如果 Promise A 在 100ms 后 reject(new Error("fail")),Promise B 在 50ms 后 resolve("B") → race 抛出 "fail" 错误(因为 B 先完成?等等——注意:这个例子中 B 更快,所以实际返回的是 "B")
- ⚠️ 正确理解:真正决定结果的是“时间上第一个 settled 的实例”。所以若 B 是 50ms resolve,A 是 100ms reject,race 结果就是 "B"
想只取最先成功的,得自己包装一层
如果业务要求“忽略失败,只等第一个成功的结果”,不能直接靠 race,需要把每个 Promise 改造成“永远不会 reject”的形式:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用
.catch(() => undefined)把错误转为 undefined(或其他哨兵值) - 再用
race,然后过滤掉无效结果(比如 undefined) - 或者更稳妥:用
Promise.allSettled+ 排序,但那就不是 race 语义了
常见写法示例:
const firstSuccess = Promise.race([fetch('/api/a').catch(() => null),
fetch('/api/b').catch(() => null),
fetch('/api/c').catch(() => null)
]).then(res => {
if (res === null) throw new Error('All failed');
return res;
});
典型用途:超时控制
这是 race 最实用的场景:给异步操作加时限。
- 把目标 Promise 和一个延迟 reject 的 Promise(如
setTimeout包装的)一起 race - 谁先结束,就按谁的结果走 —— 成功则用数据,超时则进 catch
示例:
function timeout(p, ms) {return Promise.race([
p,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), ms)
)
]);
}
timeout(fetch('/data'), 3000)
.then(res => res.json())
.catch(err => console.error('请求失败或超时:', err));
注意事项
- race 返回的是一个新的 Promise,原始 Promise 仍会继续运行(不会自动取消)
- 没有内置的“取消”机制,如需真正中断请求,要用 AbortController(Fetch API)或手动清理逻辑
- 如果传入空数组,race 会永远 pending(不会 resolve 也不会 reject)
- 如果传入非 Promise 值,会被自动 Promise.resolve() 包装
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










