ES2021 实现异步多重限制方案

阅读时长 9 分钟读完

在前端开发中,异步操作是非常常见的。但是,当需要同时执行多个异步操作时,往往会遇到一些问题。例如,如何控制异步操作的数量,如何保证它们按照指定的顺序执行等等。在 ES2021 中,引入了一些新的语言特性,可以帮助我们实现异步多重限制方案,本文将详细介绍这些特性的使用方法。

Promise.allSettled()

Promise.all() 是一个非常常用的方法,可以用来将多个 Promise 实例组合成一个新的 Promise 实例,等待所有的 Promise 实例都执行完成后再返回结果。但是,如果其中某个 Promise 实例出现了错误,整个 Promise.all() 就会失败。在这种情况下,我们就需要使用 Promise.allSettled() 方法。

Promise.allSettled() 方法也可以将多个 Promise 实例组合成一个新的 Promise 实例,但是它不会在任何 Promise 实例失败时立即失败,而是会等待所有的 Promise 实例都执行完成后,返回一个包含每个 Promise 实例执行结果的数组。例如:

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

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

上面的代码中,Promise.allSettled() 方法接收一个包含三个 Promise 实例的数组,其中第二个 Promise 实例会返回一个错误。当所有的 Promise 实例都执行完成后,Promise.allSettled() 方法会返回一个包含三个对象的数组,每个对象都包含了对应 Promise 实例的执行结果。例如:

Promise.any()

Promise.any() 方法也是一个新的语言特性,用于将多个 Promise 实例组合成一个新的 Promise 实例,等待其中任何一个 Promise 实例成功后就返回成功结果。如果所有的 Promise 实例都失败了,Promise.any() 方法就会返回一个 AggregateError 对象,其中包含了所有 Promise 实例的错误信息。例如:

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

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

上面的代码中,Promise.any() 方法接收一个包含三个 Promise 实例的数组,其中第二个 Promise 实例会返回一个成功结果。当其中任何一个 Promise 实例成功后,Promise.any() 方法就会返回一个成功结果,例如:

Promise.race()

Promise.race() 方法也是一个非常常用的方法,用于将多个 Promise 实例组合成一个新的 Promise 实例,等待其中任何一个 Promise 实例成功或失败后就返回对应的结果。例如:

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

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

上面的代码中,Promise.race() 方法接收一个包含三个 Promise 实例的数组,其中第一个 Promise 实例会在 1 秒后返回结果。当其中任何一个 Promise 实例成功或失败后,Promise.race() 方法就会返回对应的结果,例如:

async/await

async/await 是一个非常常用的异步编程语言特性,可以让我们像同步代码一样编写异步代码。在 ES2021 中,async/await 也有了一些新的特性,例如:

Promise.any() 和 Promise.allSettled() 的支持

async/await 支持使用 Promise.any() 和 Promise.allSettled() 方法,例如:

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

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

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

----------

上面的代码中,example() 函数中使用了 async/await 关键字,同时使用了 Promise.any() 和 Promise.allSettled() 方法来处理多个 Promise 实例。当其中任何一个 Promise 实例成功后,async/await 就会返回对应的结果;当所有的 Promise 实例都执行完成后,async/await 就会返回包含每个 Promise 实例执行结果的数组。

for-await-of 循环

for-await-of 循环是一个新的语言特性,可以用于遍历异步迭代器对象。例如:

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

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

----------

上面的代码中,example() 函数中定义了一个异步迭代器对象 asyncIterable,并使用 for-await-of 循环遍历了它的所有值。当异步迭代器对象还有值时,for-await-of 循环就会执行异步操作,并等待异步操作完成后再进行下一次循环。

示例代码

下面是一个使用 Promise.allSettled() 和 async/await 实现异步多重限制方案的示例代码:

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

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

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

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

----------

上面的代码中,example() 函数中定义了一个包含 10 个数字的数组 data,同时定义了一个限制并发数量的变量 limit。在 while 循环中,将数组 data 按照 limit 的数量拆分成多个 chunk,每个 chunk 中的数字都会执行一个异步操作,并返回它的值的两倍。最终,使用 Promise.allSettled() 方法将所有的 chunkPromise 组合成一个 Promise 实例,并使用 Promise.all() 方法等待所有的 Promise 实例都执行完成后,返回每个 Promise 实例执行结果的数组。最后,使用 flat() 和 filter() 方法过滤出成功的 Promise 实例,并将它们的值保存到一个新的数组中。当所有的异步操作执行完成后,会将这个新的数组输出到控制台上。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d99681a941bf713414671d

纠错
反馈