走进 ES8 新特性之 async,Promise 也是可以这么用

阅读时长 8 分钟读完

走进 ES8 新特性之 async,Promise 也是可以这么用

在前端开发中,异步操作是不可避免的,而 ES6 引入的 Promise 技术已经让异步代码更易于维护和理解。ES8 引入的 async/await 又让异步代码可读性更高,可维护性更好。现在让我们来深入了解一下 ES8 async/await 新特性。

一、Promise 回顾

在讨论 async/await 之前,我们先回顾一下 Promise。Promise 是一种异步解决方案,最主要的目标就是解决回调函数嵌套的问题。Promise 的特点是可以通过链式调用来完成多个异步操作,接受多个 then() 方法。

下面是 Promise 的示例代码:

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

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

在这个示例中,我们定义了一个 asyncAction 函数,该函数返回一个 Promise 对象。在 Promise 对象中,我们使用了 setTimeout 函数模拟了一个异步操作。当异步操作完成时,我们使用 resolve() 或 reject() 方法来完成 Promise 对象,并返回结果或错误信息。在链式调用中,使用 then() 方法获取 Promise 对象的返回值,用 catch() 方法来获取错误信息。

二、async/await 简介

async/await 是 ES8 中一个重要的新特性,可以让 JavaScript 内部函数或外部函数能够使用 Promise。使用 async/await 时,代码会看起来像同步代码,但是仍然是异步执行的。下面我们来介绍一下 async/await 的用法。

  1. async

使用 async 关键字可以让函数变成一个异步函数,异步函数返回值默认是 Promise 对象。在异步函数中使用 await 关键字时,隐式地将 Promise 对象转换成对 Promise 对象的 then 链,并且 awit 只能在异步函数内部使用。

下面是一个简单的 async 示例代码:

在这个示例中,我们定义了一个异步函数 asyncAction,函数返回值是一个字符串。在执行 asyncAction() 函数时,返回了一个 Promise 对象,紧接着通过 then() 方法链式调用,输出了字符串 'Hello, async'。

  1. await

await 关键字用于等待异步操作完成,并通过 Promise 对象获取操作结果。当 await 关键字后面的异步操作完成时,会将异步操作返回值作为 await 表达式的结果。在异步函数中使用 await 关键字时,代码不会继续执行,直到返回值或者 throw Error,则代码继续执行。

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

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

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

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

在这个示例中,我们定义了一个异步操作 asyncOperation,该操作在 1 秒钟后返回字符串 'Hello, await'。在 asyncAction 函数中,使用了 await 关键字等待异步操作的完成。当异步操作完成后,await 表达式的返回值被赋值给了 result,最终输出了字符串 'Hello, await'。

加上默认参数后的示例代码:

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

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

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

在这里,我们通过加入默认参数,每次调用 asyncOperation 函数时的返回值都不同。这个示例展示了 await 关键字执行的顺序,需要等待第一个返回后才会执行第二个。

三、async/await 与 Promise 的区别

async/await 和 Promise 都是用来处理异步任务的工具,虽然它们的最终目的一致,但是二者在细节上还是有些区别。Promise 是一个立即执行的对象,可以将其传递到需要它的地方,而 async/await 在使用时需要将其封装进一个函数内。下面是 async/await 与 Promise 的区别:

  • 可读性:async/await 代码可读性高,显然比 Promise 更加容易被理解。
  • 异常处理:通过 await 和 try/catch 语句,异常的捕捉处理方式更加简单明了。
  • 调用方式:对于 Promise,不同的 Promise 实例只能使用 then/catch 来调用处理结果,而 async/await 则可以使用普通的函数调用方式。
  • 错误说明:对于 Promise,错误提示不是很清晰;async/await 则更容易看清错误详情。

四、在实际开发中如何应用 async/await

  1. 异步 API 调用

在实际开发中,如果我们需要进行异步 API 调用,我们通常使用 Promise 对象来完成。使用 async/await 可以让代码更加简洁易懂。下面是一个简单的 ajax 请求示例代码:

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

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

在这个示例中,我们使用了 async/await 的形式,简洁易懂。使用 try/catch 语句来捕捉发生的异常,并对异常进行处理。

  1. 函数内部逻辑不需要按顺序执行

有时候我们的程序在执行时需要依赖其他的外部 API,比如用户登录以后的后续操作。在这种情况下,使用 async/await 可以让我们在函数中忽略掉这些外部 API 的调用顺序。

下面是一个在线购票示例代码:

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

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

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

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

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

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

在这个示例中,我们依次调用 checkUser() 和 getTickets() 函数,每一个函数都需要等待 1 或 2 秒钟的异步操作。由于函数内部逻辑使用了 async/await 的形式,所以即使在外部使用了 async/await,整个程序也不会被阻塞,各个异步操作会在内部独立执行,并在其完成时统一返回结果。

五、总结

在本文中,我们详细讲解了 ES8 新特性 async/await,通过示例代码进行了深入的讲解。async/await 的优点在于读写性高,代码清晰易懂,为异步操作的编写带来了许多便利。在实际开发中,我们可以通过运用类似的简单技巧来提高代码质量,写出简洁、易懂的前端代码。

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

纠错
反馈