如何在 ECMAScript 2017 中正确使用 Promise.allSettled

ECMAScript 2017 引入了 Promise.allSettled 方法,它返回一个 promise,该 promise 在所有给定的 promise 都已经 fulfilled 或者 rejected 后才会被 resolved。与 Promise.all 不同的是,Promise.allSettled 不会在任何一个 promise 被 rejected 时就立即返回,而是会等待所有 promise 都执行完毕后才进行返回。这为我们处理一些异步操作带来了更多的可能性。在今天的文章中,我们将详细探讨如何在 ECMAScript 2017 中正确使用 Promise.allSettled,并且给出一些实际案例供大家学习。

Promise.allSettled 的基本用法

Promise.allSettled 的用法与 Promise.all 类似,只不过 Promise.allSettled 不会在任何一个 promise 被 rejected 的时候立即返回,并且返回的为一个所有 promise 的状态的数组。

例如,我们有以下 3 个异步操作:

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

我们可以使用 Promise.allSettled 来等待它们完成,并获取它们的状态:

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

输出结果为:

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

其中,每个元素包含一个状态和一个值或原因。状态有两种:fulfilled 和 rejected。因为我们在这里使用的是 Promise.resolve 和 Promise.reject,所以越过了每个 promise 的状态。通常情况下,这个方法依然会等待所有的 promise 完成后才会返回。在下面的例子中,我们来看一下不同的任务如何影响返回的结果:

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

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

这里的结果会和上一个例子不一样,输出结果如下:

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

上面的代码中,p1 3 毫秒结束,p2 2 毫秒结束,p3 1 毫秒结束,因此结果按照执行的不同,变成了数组。不过值得注意的是,这个方法依然会等待所有的 promise 完成后才会返回,如果中途代码报错或者代码运行时间过长等,总时间也会相应地增加。

处理异步操作中的错误

在异步操作中,经常出现一些操作失败的情况,一般来说,当我们使用 Promise.all 的时候,如果期中的任何一个 promise 被 rejected,整个操作都会失败。但是在使用 Promise.allSettled 的时候,如果存在 rejected 的 promise,它依旧会等待所有的 promise 完成,因此我们可以在所有操作都结束后对失败的 promise 进行统一的处理。

例如,我们假设 p2 是一个失败的 promise:

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

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

经过测试,你会发现无论 p2 在数组中的位置如何,最后都会打印出:

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

这正是 Promise.allSettled 可以帮助我们简化异步处理的原因。

如何使用 Promise.allSettled 实现并行异步操作

Promise.allSettled 提供了一种并行异步操作的机制。这个机制可以与 Promise.all、Promise.race 等方法配合使用,来完成复杂的异步操作。在下面的例子中,我们将结合 Promise.allSettled 与 Promise.race 实现一个异步操作的顺序机制:

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

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

输出的结果为:

--

因为这里使用了 Promise.race 和 Promise.allSettled,因此,我们可以保证如下的情况:在完成所有任务后,它会返回“最快的一个任务的结果”。

结论

在本文中,我们简要介绍了 ECMAScript 2017 的一个新 API:Promise.allSettled。这个 API 可以帮助我们处理异步操作中被拒绝的情况,并且提供了一种并行异步操作的机制。我们可以利用它来强化我们的异步应用程序,加快程序的运行速度,并提高应用程序的完整性。

-- ----

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

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

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

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

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