手动实现一个 Promise.all。

推荐答案

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

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


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

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

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

本题详细解读

核心概念

Promise.all 的核心在于并发处理多个 Promise,并在所有 Promise 都成功 resolve 时返回一个包含所有结果的 Promise。如果其中任何一个 Promise 失败 reject,则 Promise.all 返回的 Promise 也会立即 reject

实现步骤

  1. 接收参数: Promise.myAll 接收一个 Promise 数组 promises 作为参数。
  2. 返回 Promise: 返回一个新的 Promise,该 Promise 的状态将根据所有输入 Promise 的状态而定。
  3. 空数组处理: 如果 promises 为空或不存在,则立即 resolve 一个空数组。
  4. 初始化: 初始化一个用于存储所有 resolve 结果的 results 数组,以及一个计数器 resolvedCount 来记录已 resolve 的 Promise 数量。
  5. 遍历 Promise 数组: 遍历 promises 数组。
    • 使用 Promise.resolve 包装每个数组元素,确保即使元素不是 Promise ,也能统一处理。
    • 对每一个 Promise 调用 .then 方法
    • .thenresolve 回调中:
      • resolve 的值按顺序存储到 results 数组的相应位置。
      • resolvedCount 加一。
      • 检查 resolvedCount 是否等于 totalPromises,如果是,则说明所有 Promise 都 resolve 了,调用外部 Promise 的 resolve 并传入 results 数组。
    • .thenreject 回调中:
      • 调用外部 Promise 的 reject,并将 reject 的原因传递出去。
  6. 错误处理: 如果任何一个 Promise 失败 (reject),则立即 reject 整个 Promise.all 返回的 Promise,并传递 reject 的原因。

关键点

  • 并发处理: Promise.all 需要并发处理所有的 Promise,而不是顺序处理,所以不能使用async await。
  • 顺序返回: 返回的数组顺序需要和传入的顺序保持一致。
  • 短路效应: 只要有一个 Promise reject,整个 Promise.all 都会 reject,这就是短路效应。
  • 非 Promise 值处理: 输入的 promises 数组中可能包含非 Promise 的值,所以需要使用 Promise.resolve 包装,将其转换为 Promise。
  • 空数组处理:promises 为空时,应该立即 resolve 一个空数组。
  • 错误处理: 需要正确捕获并传递 Promise 的错误。
纠错
反馈