ES7 async/await 原理

阅读时长 6 分钟读完

前言

随着 JavaScript 语言的不断发展,ES7 中新增了 async/await 关键字,用以解决异步编程带来的回调地狱问题。async/await 使得异步代码的语法更加清晰简洁,使得代码的可读性和可维护性得到了极大地提升。本文将简单介绍 async/await 的基本使用方法,着重分析 async/await 的原理,以帮助读者深入理解其工作原理。

async/await 基本使用方法

在 JavaScript 中,使用 async/await 进行异步编程,需要满足以下条件:

  • 函数声明为 async
  • await 只能在 async 函数内部使用
  • await 右侧必须是 Promise 对象,或者是能够返回 Promise 对象的函数

下面是一个简单的 async 函数示例:

在这个例子中,getAsyncData 是一个异步函数,通过 await 关键字等待 Promise 对象的返回。在这个例子中,使用 await 等待了 fetch 函数的返回结果。fetch 返回的是 Promise 对象,await 等待其异步获取到数据,并且将解析为 json 格式。函数返回 Promise 对象,当异步操作完成后 Promise 对象会被 resolve 成异步操作的结果。

async/await 实现原理

async/await 的实现原理就是生成器函数的自动执行器,也就是说,async/await 是基于生成器函数的实现。只不过 async/await 帮助我们实现了生成器函数的自动执行流程,使得生成器函数更加简单易用。

为了更好的理解 async/await 的实现原理,需要了解以下几个关键点:

生成器函数

生成器函数可以使用 yield 关键字控制函数的执行流程。配合使用 next 方法,可以使得生成器函数分多次执行,每次执行到 yield 关键字处暂停,返回到上一级函数中。下次调用 next 方法时,从暂停的位置继续执行。

下面是一个简单的生成器函数示例:

这个生成器函数每次调用 next 方法都会返回一个对象:包括 value (即 yield 关键字后面的值)和 done (表示调用 next 方法是否正常结束)。

Promise 对象

Promise 对象能够将异步操作转化为同步操作,并且使用了 then 方法控制异步操作的状态。异步操作的结果最终会被 resolve 或者 reject。

下面是一个异步操作的 Promise 对象示例:

async/await 实现原理

async 函数实际上就是生成器函数的语法糖,返回的是 Promise 对象。我们一般通过 await 关键字控制异步操作的执行流程。当 await 等待的 Promise 对象完成后,async 函数将会自动执行下一步操作。

下面是一个 async/await 示例:

在这个示例中,getAsyncData 函数使用 await 关键字等待 fetchData 函数返回 Promise 对象完成,完成后将获得数据并将数据返回。返回的数据使用 Promise 对象的形式返回,异步操作完成后 Promise 对象会被 resolve 成异步操作的结果。

实际上,async 函数等价于以下两部分代码:

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

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

其中 asyncHandle 函数就是生成器函数的自动执行器。它负责控制异步操作的执行流程,处理异步操作完成后返回的值。

当 async 函数执行时,会返回一个 Promise 对象。这个 Promise 对象在 async 函数内部实现,由 asyncHandle 函数返回。要注意的是这个 Promise 对象的状态是异步操作的状态,而不是 async 函数执行的状态。在 async 函数内部,我们使用 await 关键字等待 Promise 对象的完成。当 Promise 对象完成时,asyncHandle 函数会将 Promise 对象 resolve 为异步操作完成的结果。

总结

ES7 中加入的 async/await 关键字是解决异步编程回调地狱的一种很好的方法。async/await 帮助我们更好的控制异步编程的流程,使得代码更加清晰易读。async/await 的原理并不复杂,只要理解了生成器函数和 Promise 对象的原理,就可以轻松掌握其实现原理。学习 async/await,可以帮助我们更好的掌握 JavaScript 的异步编程,提高代码的可读性和可维护性。

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

纠错
反馈