Promise 串行、并行和限制并发的实现方式

阅读时长 10 分钟读完

Promise 是一种在前端开发中经常使用的异步编程方法。它通过链式调用的方式,使代码更加模块化和可读性强。在 Promise 的使用过程中,我们会涉及到 Promise 的串行、并行和限制并发等操作方式。本文将分别介绍这些方式的实现方法,并带有详细的示例代码。

Promise 串行

Promise 串行是指按照一定的顺序执行多个 Promise 实例,每次执行的结果需要用到上一次执行的结果。在 Promise 串行的场景中,我们需要依次执行多个异步任务,并按照顺序进行处理。Promise 串行的实现方式有两种,分别是使用 then 链式调用和 async/await 写法。

1. 使用 then 链式调用

使用 then 链式调用的方法是,将每个异步任务的结果通过 then 方法传递下去,并通过返回 Promise 实例的方式,实现链式调用。下面是基于 then 链式调用的 Promise 串行示例代码:

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

--------
  ---------- -- -
    ------------------
    ------ ---------
  --
  ---------- -- -
    ------------------
    ------ ---------
  --
  ---------- -- -
    ------------------
  ---
展开代码

上述代码中,我们分别定义了三个 Promise 实例,并分别在 1s、2s 和 3s 后,分别返回了对应的结果 1、2、3。通过链式调用的方式,我们将这三个 Promise 实例串起来,并依次输出了它们的结果。

2. 使用 async/await 写法

使用 async/await 写法的方法是,使用 async 关键字声明一个异步函数,并通过 await 关键字等待前一个异步任务完成后,再执行下一个异步任务。下面是基于 async/await 写法的 Promise 串行示例代码:

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

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

----------------
展开代码

上述代码中,我们定义了一个名为 serialPromise 的异步函数,并在其中使用了三个 await 关键字,分别等待了上一个异步任务的完成后,再执行下一个异步任务。通过这种方式,我们实现了基于 async/await 写法的 Promise 串行。

Promise 并行

Promise 并行指的是同时执行多个异步任务,并等待它们全部完成后再进行下一步处理。与 Promise 串行不同的是,在 Promise 并行中,各个异步任务之间并不会有先后执行的顺序,只有它们全部完成后才会进行下一步处理。Promise 并行的实现方式有两种,分别是 Promise.all 方法和 await Promise.all 方法。

1. Promise.all 方法

Promise.all 方法可以将多个 Promise 实例包装成一个新的 Promise 实例,并等待所有的 Promise 实例完成后,返回它们的结果。下面是基于 Promise.all 方法的 Promise 并行示例代码:

上述代码中,我们分别定义了三个 Promise 实例,并使用 Promise.all 方法将它们包装成一个新的 Promise 实例。在 Promise.all 方法的 then 方法中,我们可以得到这三个 Promise 实例的结果,并输出它们的值。

2. await Promise.all 方法

在 ES7 中,新增加了一个 Promise.all 方法的语法糖,称为 await Promise.all 方法。它可以将多个 Promise 实例包装成一个新的 Promise 实例,并等待所有的 Promise 实例完成后,返回它们的结果。下面是基于 await Promise.all 方法的 Promise 并行示例代码:

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

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

------------------
展开代码

上述代码中,我们使用了 async/await 的写法,并在其中使用了 await Promise.all 方法来实现 Promise 并行。在 parallelPromise 函数中,我们可以得到这三个 Promise 实例的结果,并输出它们的值。

Promise 限制并发

有时候,我们需要同时执行多个异步任务,但是又需要限制它们的并发数量,即每次只能执行一定数量的异步任务。在这种情况下,我们需要实现 Promise 限制并发的方式。Promise 限制并发的实现方式有两种,分别是使用 async/await 和第三方库并行控制库。

1. 使用 async/await

使用 async/await 实现 Promise 限制并发的方式是,通过控制并发数量,使得每次只有一定数量的异步任务在同时执行。下面是一个基于 async/await 限制并发的示例代码:

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

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

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

------------------------ -- -
  ---------------
---
展开代码

上述代码中,我们随机生成了 5 个异步任务,并将它们存储在 promises 数组中。在 parallelPromise 函数中,我们定义了计数器 count 和结果数组 result,来进行并发控制和存储结果。在 while 循环中,我们每次从 promises 数组中取出一个异步任务,并将其包装成一个新的 Promise 实例加入到结果数组 result 中。同时,如果当前 result 中的 Promise 数量达到了限制 maxCount,则使用 Promise.race 方法等待其中完成的 Promise 实例,并将执行计数器 count 减一。

2. 使用第三方库并行控制库

除了使用自己编写的 async/await 语法来实现 Promise 限制并发外,我们还可以使用第三方库来实现并发控制。其中最为常用的是 async 包中的控制方法。下面是基于 async 包中的控制方法来实现 Promise 限制并发的示例代码:

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

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

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

------------------------ -- -
  ---------------
---
展开代码

上述代码中,我们同样随机生成了 5 个异步任务,并将它们存储在 promises 数组中。在 parallelPromise 函数中,我们使用了 async.mapLimit 方法来设置异步任务的并发数量,并在其中使用了异步函数的写法,来实现 Promise 限制并发。

总结

本文主要介绍了 Promise 串行、并行和限制并发的实现方式。其中 Promise 串行可以通过 then 和 async/await 两种方式实现;Promise 并行可以通过 Promise.all 和 await Promise.all 两种方式实现;Promise 限制并发可以通过 async/await 和第三方库并行控制库两种方式实现。无论是哪种方式,都可以让我们更加灵活地处理异步任务,从而优化前端代码的质量和效率。

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

纠错
反馈

纠错反馈