You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Promise.race含拒绝Promise时无返回?代码疑问解析

理解Promise.race的执行逻辑:为什么你的代码没有输出43?

首先,咱们得先搞清楚你误解的核心点:当所有Promise都是同步立即完成状态时,Promise.race并不会比拼谁的“执行速度”——因为它们根本没有异步等待,状态在创建时就已经确定了。这时候race的选择逻辑是由你传入的可迭代对象(这里是数组)的遍历顺序决定的。

先拆解Promise.race的核心机制

Promise.race的工作逻辑其实很直白:

  • 它会遍历你传入的可迭代对象(比如数组)里的每一个Promise
  • 只要其中任何一个Promise进入settled状态(无论是resolved还是rejected),race返回的新Promise就会立刻继承这个Promise的状态和值
  • 但如果传入的所有Promise在race开始执行时就已经是settled状态了,那race会直接选取数组中第一个被遍历到的settled Promise作为结果——因为此时没有异步任务需要等待,所有状态都已经同步完成了。

分析你的代码为什么没有输出

看你写的代码:

let p1 = new Promise((resolve, reject) => { resolve(42); }); 
let p2 = Promise.reject(43); 
let p3 = new Promise((resolve, reject) => { resolve(44); }); 
let p4 = Promise.race([p1, p2, p3]); 
p4.catch((value) => { console.log(value); }); 

这里的三个Promise都是同步完成状态:

  • p1:在Promise构造函数执行时,同步调用了resolve(42),所以它在创建完成的瞬间就处于resolved状态
  • p2:Promise.reject()方法会直接同步返回一个rejected状态的Promise
  • p3:和p1一样,同步调用resolve(44),瞬间resolved

当你调用Promise.race([p1, p2, p3])时,数组里的三个Promise都已经是settled状态了。race会按数组顺序(p1 → p2 → p3)遍历,第一个遇到的settledPromise是p1(状态resolved,值42),所以p4会变成一个resolved状态的Promise,值为42。

而你只给p4注册了catch回调——这个回调只会在Promise被rejected时触发,p4是resolved的,自然不会执行catch,所以没有任何输出。

验证和修正的例子

如果给p4加上then回调,就能看到输出42:

let p1 = new Promise((resolve, reject) => { resolve(42); });
let p2 = Promise.reject(43);
let p3 = new Promise((resolve, reject) => { resolve(44); });
let p4 = Promise.race([p1, p2, p3]);
p4.then((value) => { console.log(value); }) // 输出42
   .catch((value) => { console.log(value); });

如果想让p2成为race的结果,你可以把它放在数组的第一个位置:

let p4 = Promise.race([p2, p1, p3]);
p4.catch((value) => { console.log(value); }); // 此时会输出43

如果要模拟真正的“异步竞速”场景,让p1和p3延迟完成,p2同步拒绝,那p2会先进入settled状态,触发catch:

let p1 = new Promise((resolve) => setTimeout(() => resolve(42), 100));
let p2 = Promise.reject(43);
let p3 = new Promise((resolve) => setTimeout(() => resolve(44), 50));
let p4 = Promise.race([p1, p2, p3]);
p4.catch((value) => { console.log(value); }); // 输出43

总结

Promise.race的“竞速”比的是哪个Promise先进入settled状态:

  • 当所有Promise都是同步完成时,数组的遍历顺序决定了结果
  • 只有当存在异步操作时,才会真正比拼异步回调的触发顺序(也就是你原本以为的“执行速度”)

内容的提问来源于stack exchange,提问作者landscape1250

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:57:14