使用 Promise.all 实现多个网络请求的并发调用

阅读时长 7 分钟读完

在前端开发中,经常需要同时发起多个网络请求,等待它们都返回结果再进行下一步操作。通常的做法是采用异步回调,这样就可以发起多个请求后进行异步等待,并在所有请求都结束后进行处理。但是在 ES6 中,我们可以使用 Promise.all 来达到并发调用多个网络请求的目的。

本文将详细地介绍 Promise.all 的使用方式,并通过实例代码演示其使用。

Promise.all 的基本使用

Promise.all 可以接收一个由 Promise 组成的数组作为参数,返回一个新的 Promise 对象。在所有 Promise 都成功完成时,Promise.all 返回的 Promise 对象为成功状态。如果其中任何一个 Promise 是失败状态,那么 Promise.all 返回的 Promise 对象为失败状态。

我们来看一下 Promise.all 的基本使用:

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

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

代码中定义了三个 Promise 对象,它们分别在 1 秒、2 秒和 3 秒之后返回不同的结果。使用 Promise.all 并传入这三个 Promise 对象的数组,Promise.all 会在三个对象都成功完成后返回一个包含这三个结果的成功状态的 Promise 对象。

并发调用多个网络请求

当我们在前端进行多个网络请求时,通常需要等待它们都返回结果后才能进行下一步操作。这时,可以使用 Promise.all 并发调用多个网络请求,最终等待所有请求都返回成功结果后再进行下一步处理。

假设我们需要调用两个后端接口,一个返回 user 信息,另一个返回 order 信息。我们可以使用 Promise.all 来同时调用这两个接口,等待返回结果后再进行下一步的处理:

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

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

代码中使用了 fetch 函数来获取 user 和 order 两个接口的数据,并将返回的 Promise 对象传入 Promise.all,最终等待两个接口都返回结果后在 then 回调函数中处理结果。

Promise.all 的注意点

在实际使用中,我们也需要注意一些细节,避免出现不必要的问题。

优化代码结构

Promise.all 可以将多个网络请求的结果一起返回,但是代码实现时,仍然需要对每一个网络请求的数据进行处理。为了提高代码的可读性和可维护性,我们可以使用 async/await 来优化代码结构。

在上面的代码中,我们使用 async/await 来获取两个接口的数据。async 函数本身返回的就是一个 Promise 对象,所以可以直接在函数中使用 Promise.all,然后使用 await 关键字等待结果返回。最终的结果会被解构为 user 和 order 两个变量,以便进一步的处理。

错误处理

在进行多个网络请求时,难免会遇到某一个请求失败的情况。在使用 Promise.all 时,可以使用 catch 方法来处理错误的情况。

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

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

在上面的代码中,我们只需要调用 Promise.all 后使用 then 回调函数进行数据处理,用 catch 方法来捕捉错误。如果任何一个 Promise 失败,就会进入到 catch 回调函数中进行错误处理。

并发数限制

在实际项目中,我们可能需要限制并发请求数量,以防止过多的网络请求影响性能。在这种情况下,可以使用递归方式来限制并发请求数量。

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

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

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

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

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

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

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

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

在上面的代码中,我们定义了一个名为 fetchUrls 的 Promise 函数,它接收一个数组 urls 和并发请求数量 limit。在函数中定义了一个名为 fetchUrl 的递归函数,通过递归方式来控制并发请求数量。在 fetchUrl 函数内部,先使用 index 变量来记录当前已发出的请求。然后使用 async/await 异步等待 fetch(url) 方法的结果,并将其 push 进 results 数组中,最后判断是否需要继续下去,如果需要,则再次调用 fetchUrl 函数。

在 fetchUrls 函数中,我们首先创建了一个名为 results 的数组来保存请求的结果,然后创建了一个名为 promises 的数组,用来保存并发的请求数。在 for 循环中,我们使用 promises.push(fetchUrl()),往 promises 中添加 fetchUrl 函数的执行结果,并同时执行 limit 次。最后使用 Promise.all(promises) 异步等待所有异步操作完成,才会进入到下一步的处理中。

结论

Promise.all 可以很方便地实现对多个网络请求的并发调用,集中处理返回的结果并优化代码结构。但是,在使用过程中,我们也需要注意错误处理和并发数等问题。掌握 Promise.all 的使用方式,可以使我们的开发更为高效和可靠。

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

纠错
反馈