async函数需配合Promise.race()或Promise.any()实现竞态控制:race取首个settled结果(含reject),any取首个fulfilled结果(全reject才reject);二者均支持直接await,但需注意错误处理、超时封装及来源标识。

async 函数本身不直接处理 Promise 的竞态(race)条件,但可以轻松配合 Promise.race() 或 Promise.any() 实现对多个异步操作的竞态控制。
用 Promise.race() 获取最快完成的结果
当多个 Promise 同时发起,只需第一个 settled(fulfilled 或 rejected)结果时,用 race 最合适。注意:只要有一个 Promise 被 reject,race 就会立即 reject,除非你主动捕获错误。
- 在 async 函数中直接 await
Promise.race([...]) - 若希望“忽略单个失败、只取首个成功”,需提前把每个 Promise 包装成永不 reject 的形式(例如
p().catch(() => undefined)) - 示例:请求多个 CDN 地址,取响应最快的静态资源
用 Promise.any() 获取首个成功的 Promise
Promise.any() 在至少一个 Promise 成功时就 resolve,全部失败才 reject(返回 AggregateError)。它比 race 更适合“容错式竞态”场景。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 支持在 async 函数中直接 await,语法简洁
- 适用于 API 备用地址、降级策略(如主服务挂了自动切到备用服务)
- 注意:Node.js 15+ 和现代浏览器支持;旧环境需 polyfill
手动控制竞态逻辑:封装可取消或超时的 Promise
原生竞态方法无法中断已启动的 Promise,若需“某 Promise 胜出后取消其余”,需额外封装:
立即学习“Java免费学习笔记(深入)”;
- 用
AbortController配合 fetch 实现请求取消(仅限支持 abort 的 API) - 自定义 timeout 包装器:
Promise.race([p, new Promise((_, r) => setTimeout(() => r(new Error('timeout')), ms))]) - 结合 async 函数,可统一处理超时、取消、优先级等复合逻辑
避免常见陷阱
竞态不是万能方案,误用容易引发隐蔽问题:
- 不要在 race/any 中混入无意义的长耗时 Promise(如未设 timeout 的数据库查询),否则拖慢整体响应
-
await Promise.race([p1, p2])不会阻止 p1/p2 继续执行,只是提前消费结果;后续仍可能触发副作用(如重复提交) - 竞态结果不包含“是哪个 Promise 完成”的上下文,如需区分来源,建议用
{ promise, id }结构包装

















