Promise.race本身不创建微任务,仅同步监听多个Promise的首个状态变化并透传结果;其调度依赖被race的Promise内部状态变更时机,后续.then仍是标准微任务。
Promise.race 本身不创建微任务,它只是监听多个 Promise 的首个状态变化,并将那个结果(无论 fulfilled 还是 rejected)同步“透传”给它的返回 Promise。 它的调度行为完全依赖于被 race 的那些 Promise 内部如何触发状态变更,以及这些变更何时被推入微任务队列。
与 .then() 不同,Promise.race() 调用本身是同步执行的。它不会立即向微任务队列添加任何回调。它做的只有一件事:为传入的每个 Promise 实例注册一个内部的“完成监听器”。当其中任意一个 Promise 状态变为 fulfilled 或 rejected 时,race 返回的那个新 Promise 就会以相同的结果立即 settle(即进入 fulfilled 或 rejected 状态)。
这个 settle 动作本身会触发后续链式调用(比如 .then())的回调——而这些回调,才是真正的微任务。
race 的“竞速”结果取决于哪个被监听的 Promise 最先完成其状态变更逻辑。关键点在于:
resolve('a'),那它属于同步 resolve,其 .then() 回调会在当前宏任务末尾、微任务阶段执行;setTimeout(() => resolve('b'), 0),那它的 resolve 会发生在下一个宏任务,因此它的 .then() 一定晚于前者;Promise.race([syncP, timeoutP]) 的结果一定是 syncP 的值,且 race 返回的 Promise 的 .then() 会排在本轮微任务队列靠前位置。一旦 race 返回的 Promise 状态确定,你对其调用的 .then()、.catch() 就和普通 Promise 一样:回调被放入微任务队列,等待当前同步代码执行完毕后统一清空。
例如:
console.log('1');输出顺序是 1 → 3 → 2: fast,因为 .then() 是微任务,严格遵循“同步 → 微任务 → 宏任务”的事件循环规则。
race 不会取消或中断其他仍在运行的 Promise。它只关心“谁第一个完成”,其余 Promise 继续执行,可能产生副作用(如多余的网络请求、未清理的定时器)。若需真正取消,应配合 AbortController 或手动设计可取消逻辑,不能依赖 race 本身。