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

自行实现的Promise.race()返回结果不符合预期,是什么原因导致的?

Promise.race自定义实现异常原因分析

问题根因

核心问题出在你对promise回调的绑定方式:你当前使用p.then(resolve).catch(reject)的写法,导致reject回调的触发时机晚于同队列中其他已resolve状态promise的resolve回调。

p.then(resolve).catch(reject)等价于p.then(resolve, undefined).then(undefined, reject),本质是两级promise链式调用:

  1. 当输入的p是rejected状态时,第一个then没有传入onRejected处理函数,会直接返回一个新的rejected状态的promise
  2. 你绑定的reject回调实际是挂载在这个新返回的promise上,而非原始的p上
  3. 这就导致rejected状态的p的回调入队顺序,比直接在p上绑定onRejected要晚一个微任务周期

在你的测试用例中:

  • 第一个Promise.reject('test_error')的reject回调要等到第二级promise的微任务才会执行
  • 第二个Promise.resolve('test_value')的resolve回调直接挂载在原始promise上,会在第一级微任务就执行

因此会先触发resolve('test_value'),而Promise状态一旦敲定就不会再变更,最终你得到的是不符合预期的test_value。

修复方案

把回调绑定方式修改为直接给then传入两个参数,同时绑定onFulfilled和onRejected回调,确保两个回调都挂载在原始promise上,执行顺序和promise状态变更顺序一致:

const promiseRace = promises => new Promise((resolve, reject) => {
  promises.forEach(p => {
    if (
      typeof p === 'object'
          && 'then' in p
          && typeof p.then === 'function'
    ) {
      // 直接给then传两个参数,不要链式调用catch
      p.then(resolve, reject);
    } else {
      resolve(p);
    }
  });
});

修改后测试promiseRace([Promise.reject('test_error'), Promise.resolve('test_value')])会正确返回test_error,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:24:03