JavaScript 异步函数 async/await

异步函数是将期约应用于 JavaScript 函数的结果。异步函数可以暂停执行,而且不阻塞主线程。异步函数就是 async/await,它是 Es8 新增的。
不知道异步的可以看这个https://xie.infoq.cn/article/41b83acafff1bde51e2cbdd41
async
async 关键字用于声明异步函数,它可以在函数声明,函数表达式还有箭头函数上使用。
使用 async 关键字可以让函数具有异步特征,在实际中它需要和 await 配合使用。
await
一旦定义了一个函数作为一个异步函数,我们就可以使用 await 关键词。这个关键词放在回调的 Promise 之前,将会暂停执行函数,直到 Promise 执行或拒绝。
await 关键字会暂停执行异步函数后面的代码,它这个行为和生成器函数中的 yield 关键字是一样的,await 关键字也是解包对象的值,任何将这个值传给表达式,再用异步恢复异步执行的操作。
停止和恢复执行
来个小栗子,大家看看能不能猜对执行操作,再从中理解一下。
哈哈哈,其实是倒叙排列的。

await 关键字其实很简单,js 运行在碰到 await 关键字时,会记录在哪里暂停执行。等到 await 右边的值可以使用了,就是处理完回调了,js 会向消息列对中推送一个任务,这个任务会恢复异步函数的执行。这样的话,即使 await 后面跟着一个立即可用的值,函数的其余部分也会被异步求值。
异步函数并不能真正的替代 Promise。但两个可以一起携手合作。一个异步函数将 await 执行一个 Promise 和一个异步函数始终返回一个 Promise。
栈追踪和内存管理期约和异步函数的功能差不多,但他们在内存中的表示差别很大。function fooPromiseExecutor(resolve, reject) {setTimeout(reject, 1000, 'jackson');}

们可以看到错误信息包含嵌套函数的标识符,那是被调用以创建最初期约实例的函数,其实函数已经返回了,因此栈追踪不应该看到他们。
js 引擎会在创建期约时候尽可能保存完整的调用栈,在抛出错误的时候,调用栈可以由运行时的错误处理逻辑数据获取,因而就会出现在栈追踪信息中。这样肯定会占用更多的计算成本和内存。
把以上的例子换成异步函数,我们看一下

这样变成异步函数,栈追踪信息救能准确的反应当前的调用栈。fooPromiseExecutor 已经返回,所以它不存在错误细腻些中。foo 已经被挂起了,并没有退出。js 在运行时可以简单嵌套函数中存储指向包含函数的指针,相当于同步函数调用栈一样,它不会像期约那样带来额外的消耗,结果不言而喻,我们在重视性能的时候可以有限考虑异步。
版权声明: 本文为 InfoQ 作者【大熊G】的原创文章。
原文链接:【http://xie.infoq.cn/article/8f6466524b3093c4e6444e4cf】。文章转载请联系作者。
评论