一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Promise.race 的异步调度机制及微任务优先级

时间:2026-07-05 11:38:47 编辑:袖梨 来源:一聚教程网

Promise.race本身不创建微任务,仅同步监听多个Promise的首个状态变化并透传结果;其调度依赖被race的Promise内部状态变更时机,后续.then仍是标准微任务。

Promise.race 本身不创建微任务,它只是监听多个 Promise 的首个状态变化,并将那个结果(无论 fulfilled 还是 rejected)同步“透传”给它的返回 Promise。 它的调度行为完全依赖于被 race 的那些 Promise 内部如何触发状态变更,以及这些变更何时被推入微任务队列。

Promise.race 不是微任务的发起者

.then() 不同,Promise.race() 调用本身是同步执行的。它不会立即向微任务队列添加任何回调。它做的只有一件事:为传入的每个 Promise 实例注册一个内部的“完成监听器”。当其中任意一个 Promise 状态变为 fulfilled 或 rejected 时,race 返回的那个新 Promise 就会以相同的结果立即 settle(即进入 fulfilled 或 rejected 状态)。

这个 settle 动作本身会触发后续链式调用(比如 .then())的回调——而这些回调,才是真正的微任务。

实际执行顺序由被 race 的 Promise 决定

race 的“竞速”结果取决于哪个被监听的 Promise 最先完成其状态变更逻辑。关键点在于:

  • 如果某个 Promise 在构造函数中直接 resolve('a'),那它属于同步 resolve,其 .then() 回调会在当前宏任务末尾、微任务阶段执行;
  • 如果另一个 Promise 是 setTimeout(() => resolve('b'), 0),那它的 resolve 会发生在下一个宏任务,因此它的 .then() 一定晚于前者;
  • 所以 Promise.race([syncP, timeoutP]) 的结果一定是 syncP 的值,且 race 返回的 Promise 的 .then() 会排在本轮微任务队列靠前位置。

race 后续的 .then 是标准微任务

一旦 race 返回的 Promise 状态确定,你对其调用的 .then().catch() 就和普通 Promise 一样:回调被放入微任务队列,等待当前同步代码执行完毕后统一清空。

例如:

console.log('1');
Promise.race([
  Promise.resolve('fast'),
  new Promise(r => setTimeout(() => r('slow'), 10))
]).then(v => console.log('2:', v));
console.log('3');

输出顺序是 1 → 3 → 2: fast,因为 .then() 是微任务,严格遵循“同步 → 微任务 → 宏任务”的事件循环规则。

常见误用:把 race 当作“强制提前结束”工具

race 不会取消或中断其他仍在运行的 Promise。它只关心“谁第一个完成”,其余 Promise 继续执行,可能产生副作用(如多余的网络请求、未清理的定时器)。若需真正取消,应配合 AbortController 或手动设计可取消逻辑,不能依赖 race 本身。

热门栏目