为何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状态的Promisep3:和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
相关产品推荐
相关产品推荐

