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

JavaScript Promise.race无法同步resolve?如何修改代码输出two?

问题描述

MDN提供了Promise.race的示例,但该示例因无依赖竞态结果的代码存在一定误导性。我对代码调整后出现异常行为:运行下方代码时,最后一行console.log输出的是'zero'。我原本以为调用Promise.race的then方法会使执行同步,但实际并非如此。请问需要修改哪里才能让最后一行日志输出'two'?

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

(async () => {
  let val = 'zero';
  Promise.race([promise1, promise2]).then((result) => {
    val = result;
    console.log("Assigned value", val);
  })
  console.log(val);
})();
解决方案

问题出在异步代码的执行顺序上:Promise.race()是异步操作,它的then回调会被放入微任务队列,要等当前同步代码全部执行完才会运行。而最后一行的console.log(val)是同步代码,会在then回调执行前就运行,所以此时val还是初始值'zero'。

要让最后一行输出'two',有两种简单的修改方式:

方式一:用await等待异步结果

既然已经在async函数中,直接用await获取Promise.race的结果,这样代码会暂停等待Promise完成,再执行后续逻辑:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

(async () => {
  let val = 'zero';
  // 等待Promise.race完成,拿到结果后再赋值
  val = await Promise.race([promise1, promise2]);
  console.log("Assigned value", val);
  console.log(val); // 此时val已更新为'two'
})();

方式二:将console.log移入then回调

如果不想用await,就把依赖异步结果的代码放在then的回调内部,确保它在Promise完成、val被更新后再执行:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

(async () => {
  let val = 'zero';
  Promise.race([promise1, promise2]).then((result) => {
    val = result;
    console.log("Assigned value", val);
    console.log(val); // 移入回调,保证在赋值后执行
  })
})();

核心逻辑是:异步操作不会阻塞同步代码的执行,必须通过等待(await)或者把后续逻辑绑定到异步回调中,才能确保拿到更新后的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:55:17