如何解决 Promise.all 遇到 reject 只执行部分 promise 的问题

使用 Promise.all 可以同时执行多个 promise,并在所有 promise 都完成(即所有 promise 都 fulfilled 或有至少一个 promise rejected)后返回结果。但是,如果其中有一个 promise 被 reject,Promise.all 就会立即终止,并返回一个拒绝的 promise。

这种行为有时可能会带来麻烦,因为在某些情况下我们需要知道所有 promise 的状态,而不仅仅是它们中的一些。

在本文中,我们将讨论如何解决 Promise.all 遇到 reject 只执行部分 promise 的问题。

使用 Promise.allSettled

ES2020 引入了 Promise.allSettled 方法,该方法会执行所有的 promise,并等待所有 promise 都 settled(已完成,即 fulfilled 或 rejected),然后返回一个数组,该数组包含每个 promise 的状态和结果。

Promise.allSettled 返回的数组的每个元素都是一个包含以下两个键的对象:

  • status:表示 promise 的状态,可以是 "fulfilled""rejected"
  • valuereason:分别表示 promise fulfilled 的结果和 rejected 的原因

以下是 Promise.allSettled 的示例代码:

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

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

上面代码中,promise2 是个 rejected 的 promise,但是 Promise.allSettled 仍然会等待所有 promise 都 settled,然后返回一个数组,该数组包含每个 promise 的状态和结果:

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

使用 Promise.allSettled 可以确保我们处理了所有 promise 的状态,并避免了因为某个 promise 被 reject 导致我们无法获取所有 promise 的状态的情况。

但是,我们可能仍然需要利用 Promise.all 的并行特性,以实现更高效的编程。

手动计数器

我们可以手动跟踪所有 promise 的状态,并在所有 promise settled 后自己返回一个数组。

以下是手动计数器的示例代码:

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

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

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

上面代码中,我们创建了一个 Promise 对象,并在这个对象中对所有 promise 的状态进行了跟踪。当每个 promise 完成时,我们按照其状态更新计数器和结果数组。在所有 promise 都 settled(已完成,即 fulfilled 或 rejected)后,我们能够返回一个数组,该数组包含每个 promise 的状态和结果。

这种方法手动维护计数器会比 Promise.allSettled 更冗长且容易出错,但在某些情况下,这可能是必须的。

结论

在某些情况下,我们需要知道所有 promise 的状态,并且不想因为某个 promise 被 reject 而失去对其他 promise 状态的跟踪。对于这种情况,我们可以使用 Promise.allSettled。

但有时我们需要更高效地处理多个 promise。在这种情况下,我们可能需要手动跟踪所有 promise 的状态,并在所有 promise settled 后自己返回一个数组。

虽然我们可以使用这两种方法处理 Promise.all 遇到 reject 只执行部分 promise 的问题,但我们应该选择适合我们特定情况的方法。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67188adfad1e889fe22c56f1