如何尽可能使用 Async Await(ES8/ES2017)?

阅读时长 8 分钟读完

异步编程一直是前端开发中的重要话题。在多数情况下,我们使用回调函数或者 Promise 来处理异步操作。但是,ES8(ES2017)中新增的 Async Await 却可以让异步编程更加方便和可读性。

那么,在本文中,我们将会详细讲述什么是 Async Await,如何使用它来编写更好的异步代码,并告诉你一些常见的错误以及如何避免它们。

什么是 Async Await?

Async Await 是 ES2017 的新特性,它是一个更加简单的异步编程方法。async 和 await 关键字可以被添加到任何函数之前,并且可以让函数的行为变成异步的。

Async 表示函数是异步的,而 Await 表示需要等待异步操作执行完成,才能继续往下执行。这就允许开发者使用同步的语法而不至于阻塞线程。

Async 函数始终返回一个 Promise 对象,并且可以在函数体中使用 Await。

下面是一些示例代码:

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

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

上面这个函数可以异步地获取数据,并在 data 变量中存储 JSON 响应。可见,通过 async 和 await,代码变得更加简单易读。

如何正确地使用 Async Await?

Async Await 简化了开发者的异步代码,但是在使用它之前,我们需要考虑一些最佳实践:

1. 将 Async Await 与 Promise 相结合

Async Await 和 Promise 并不是彼此替代的关系。相反,它们可以一起使用来实现更好的异步代码。

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

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

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

上面的代码清晰地表明了 Async Await 和 Promise 相结合的优势。

2. 使用 try-catch 模块处理错误

使用 Async Await 的好处之一是可以使用 try-catch 模块来处理错误。如果异步方法的任何部分发生错误,try-catch 模块将会捕获它。

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

3. 防止过度嵌套

使用 Async Await 可以让代码变得更加简单易读,但是过度嵌套还是需要避免。当然,Promise 当中也同样需要注意此类问题。

以下是一个过度嵌套的代码示例:

可以使用 Promise.all() 来解决这个问题:

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

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

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

4. 不要阻塞 UI 线程

异步操作需要耗费时间,可能会让 UI 线程被阻塞。我们需要通过异步的方式来尽量避免这种情况。

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

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

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

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

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

5. 我们仍然需要了解 Promise

Async Await 比 Promise 更加简单易读,但是得益于 Promise, Async Await 才能更好地工作。所以,我们还需要了解 Promise 的使用。

下面是一个 Promise 的代码示例:

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

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

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

常见的错误

不正确地使用 Async Await 可能会引发以下两种常见错误。

1. 忘记使用 await

需要使用 await 来等待异步操作完成并继续执行,否则代码将会向下继续执行,甚至不等待异步操作完成。

上面的代码将会返回一个 Promise,而不是预期的 JSON 数据。

2. 没有捕获异常

我们还需使用 try-catch 模块来处理异常。如果没有捕获异常,代码将会停止执行,并且我们无法得知异常的原因。

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

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

上面的代码可能会因为网络问题而抛出异常,但是我们没有处理它。

结论

Async Await 是一种非常强大的异步编程方法,使得我们的代码变得更加简单易读。然而,需要注意一些要点和注意事项来确保代码的质量和可读性。同时,我们也需要深入了解 Promise,因为它与 Async Await 是紧密相连的。

最后,希望这篇文章能够帮助你更加深入地了解 Async Await,并在你的异步代码中使用它。

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

纠错
反馈