如何重构你的 async/await 代码,让它更加易读和可维护 (ECMAScript 2021 (ES12))

阅读时长 9 分钟读完

随着 JavaScript 的发展,async/await 已成为前端开发中异步编程的主流。它通过简单明了的语法,让我们可以更加便捷地处理异步代码。但是,当应用中的异步操作增多时,async/await 的代码也可能变得难以阅读和维护。本文将介绍如何重构你的 async/await 代码,让它更易读、可维护。

1. 了解 async/await

在深入讨论如何改善 async/await 代码之前,我们需要先了解它的基本用法和一些注意点。

async/await 是使用 Promise 进行异步编程的语法糖,使用 async 关键字标记一个函数为异步函数。异步函数内部可以通过 await 关键字等待异步操作完成。以下是一个简单的例子:

在这个例子中,我们使用 async 函数声明了一个异步函数 fetchData。在函数内部,我们使用 await 等待一个 HTTP 请求并解析 JSON 返回值。然后,我们将获取到的数据返回。

需要注意的是:

  • async 函数返回一个 Promise 对象,调用方可以使用 then 方法获取函数的返回值。
  • 如果 await 所等待的 Promise 被拒绝,会抛出一个异常,我们需要在调用方使用 try/catch 来处理它。
  • 可以将多个 async/await 语句串联起来,实现连续的异步处理。

2. 使用 Promise.all

当我们需要同时处理多个异步操作时,可以使用 Promise.all 方法。它接收一个 Promise 的数组作为参数,并返回一个 Promise 对象,该 Promise 对象在所有 Promise 都已解决时才被解决,否则会在任何一个 Promise 被拒绝时被拒绝。以下是一个例子:

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

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

在这个例子中,我们使用 Promise.all 等待了三个异步操作,然后将它们返回的数据存储在 requestData1、requestData2 和 requestData3 中。

如果我们先后发送请求,那么我们的请求就会变成串行,而如果我们同时发送所有请求,那么就可以实现并行请求,缩短请求时间。

3. 使用 for...of 循环

当需要对一个数组中的元素进行异步操作时,我们可以使用 for...of 循环。

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

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

在这个例子中,我们使用 for...of 循环遍历了所有 URL 数组,并对每个 URL 发起 HTTP 请求,然后解析 JSON 数据并将其存储在 results 数组中。

需要注意的是,使用 for...of 循环可以保证异步操作的顺序和顺序执行,这在某些情况下是必需的。而如果不需要保证顺序,可以使用 Promise.all 方法,如上述第二部分所示。

4. 避免过深的嵌套

async/await 经常用于处理嵌套的异步操作。然而,嵌套的代码会变得很难阅读和维护。因此,在使用 async/await 时,避免嵌套过深是非常有必要的。

以下是一个嵌套深度过高的例子:

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

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

在这个例子中,我们的代码嵌套非常深,不易于阅读和维护。我们可以重构这个例子,将它以链式调用的方式书写,使代码更加清晰易读。

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

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

以上代码中,我们使用 Promise.all 在请求多个 item 数据时并行发起请求。使用 map 对处理过的数据进行遍历是避免嵌套过深的另一种方式。

5. 使用 async 函数组合器

随着应用复杂度的提高,有时同一个函数需要处理多个异步操作,这时就需要考虑如何组合多个 async 函数。而我们可以使用 async 函数组合器来实现这一点。

一个简单的 async 函数组合器实现如下:

这个组合器接收多个 async 函数作为参数,并返回一个新的 async 函数。该函数会将传入的函数按顺序执行,并把每个函数的返回值传入下一个函数中。

以下是一个例子:

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

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

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

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

在这个例子中,我们使用了组合器,将两个异步函数串联起来,并调用它们以处理获取到的数据。

结论

在编写异步代码时,async/await 已成为前端开发者的首选方式。但是,在处理多个异步操作时,async/await 的代码也可能变得混乱和难以维护。本文介绍了使用 Promise.all、for...of 循环、避免过深嵌套、和 async 函数组合器等技术,以提高异步代码的可读性和可维护性。希望这些技巧能够帮助你编写更加优雅的 async/await 代码。

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

纠错
反馈