手动实现一个 Promise.race。

推荐答案

-- -------------------- ---- -------
------------ - -------- ---------- -
  ------ --- ----------------- ------- -- -
    -- ---------- -- --------------- --- -- -
      ---------- -- -- ---------- ------------------ ---- -------- ---- ------------ ------
      -------
    -

    --- ------ ------- -- --------- -
      -------------------------------------- --------
    -
  ---
--

本题详细解读

题目要求

手写实现 Promise.race 方法。Promise.race 接收一个 Promise 数组,并返回一个新的 Promise。新 Promise 的状态和值取决于数组中第一个 settled(即 fulfilled 或 rejected)的 Promise。

实现思路

  1. 创建并返回新的 Promise: Promise.race 本身需要返回一个新的 Promise,这是异步操作的基本结构。

  2. 处理空数组情况: 如果传入的 promises 数组为空,根据 ECMAScript 标准,返回的 Promise 应该立即 resolve 一个 undefined 值。(也有实现会直接reject一个 AggregateError,看具体需求)。

  3. 遍历 Promise 数组: 使用 for...of 循环遍历输入的 promises 数组。

  4. 处理非 Promise 值: 使用 Promise.resolve() 将遍历到的元素转换为 Promise,确保能够使用 .then()。这可以使 Promise.race 能够处理非 Promise 的值,如普通值或 thenable 对象。

  5. 绑定 then 处理: 对于每一个转换后的 Promise,使用 .then(resolve, reject) 方法,其中 resolvereject 直接来自外部创建的 Promise

  • 一旦有任何一个 Promise fulfilled,外层的 Promise 将立即 resolve,并携带该值。
  • 一旦有任何一个 Promise rejected,外层的 Promise 将立即 reject,并携带该原因。
  • 注意:这里关键在于,第一个 settled 的 Promise 将决定返回 Promise 的状态和值,后续的 settled 的 Promise 将被忽略。
  1. 返回新 Promise: 返回创建的 Promise 实例。

代码解释

  • Promise.race = function (promises) { ... }: 定义 Promise.race 函数,并接受 Promise 数组 promises 作为参数。
  • return new Promise((resolve, reject) => { ... }): 创建并返回一个新的 Promise,其状态和值将在内部异步决定。
  • if (!promises || promises.length === 0) { resolve(); return;}: 处理传入空数组的情况,直接resolve。
  • for (const promise of promises) { ... }: 循环遍历 promises 数组。
  • Promise.resolve(promise).then(resolve, reject);: 使用 Promise.resolve() 将数组项转换为 Promise,然后使用 .then() 绑定 resolve 和 reject 处理。
  • 一旦 then 方法被调用,无论 resolve 或 reject,都会触发外部 Promise 的状态变更,并且由于 race 的特性,只会触发一次,后面的都不会生效。

关键点

  • 短路行为: race 的关键在于“短路”行为,即第一个 settled 的 Promise 决定最终结果。
  • Promise.resolve(): Promise.resolve() 将非 Promise 值转换为 Promise,确保 then() 可以被调用。
  • 错误处理: 本实现中,任何一个 Promise reject,外部返回的 Promise 也会 reject。
纠错
反馈