家电维修网

 找回密码
 注册
家电维修网 网站首页 电工学习 查看内容

V8中更快的异步函数和promises

2018-12-1 12:41| 发布者: 南召修电视| 查看: 1341| 评论: 0

摘要: 原文作者:Maya Lekova and Benedikt Meurer 译者:UC 国际研发 Jothy写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与 ...
V8中更快的异步函数和promises


异步函数的真正威力来自 await 表达式,它使函数执行暂停,直到 promise 完成之后,再恢复函数执行。 await 的值是 promise fulfilled(完成)的结果。 这个示例可以很好地解释:


fetchStatus 在 await 处暂停,在 fetch promise 完成时恢复。 这或多或少等同于将 handler 链接到 fetch 返回的 promise。


该 handler 包含 async 函数中 await 之后的代码


一般来说你会 await 一个 Promise,但其实你可以 await 任意的 JavaScript 值。 就算 await 之后的表达式不是 promise,它也会被转换为 promise。 这意味着只要你想,你也可以 await 42:


更有趣的是,await 适用于任何 “thenable”,即任何带有 then 方法的对象,即使它不是真正的 promise。 因此,你可以用它做一些有趣的事情,例如测量实际睡眠时间的异步睡眠:


让我们按照规范看看 V8 引擎对 await 做了什么。 这是一个简单的异步函数 foo:


当 foo 被调用时,它将参数 v 包装到一个 promise 中,并暂停异步函数的执行,直到该 promise 完成。完成之后,函数的执行将恢复,w 将被赋予 promise 完成时的值。 然后异步函数返回此值。


>> V8 如何处理 await <<


首先,V8 将该函数标记为可恢复,这意味着该操作可以暂停并稍后恢复(await 时)。 然后它创建一个叫 implicit_promise 的东西,这是在调用异步函数时返回的 promise,并最终 resolve 为 async 函数的返回值。



简单的异步函数以及引擎解析结果对比


有趣的地方在于:实际的 await。首先,传递给 await 的值会被封装到 promise 中。然后,在 promise 后带上 handler 处理函数(以便在 promise 完成后恢复异步函数),而异步函数的执行会被挂起,将 implicit_promise 返回给调用者。一旦 promise 完成,其生成的值 w 会返回给异步函数,异步函数恢复执行,w 也即是 implicit_promise 的完成(resolved)结果。


简而言之,await v 的初始步骤是:

1. 封装 v - 传递给 await 的值 - 转换为 promise。

2. 将处理程序附加到 promise 上,以便稍后恢复异步函数。

3. 挂起异步函数并将 implicit_promise 返回给调用者。


让我们一步步来完成操作。假设正在 await 的已经是一个已完成且会返回 42 的 promise。然后引擎创建了一个新的 promise 并完成了 await 操作。这确实推迟了这些 promise 下一轮的链接,正如 PromiseResolveThenableJob 规范表述的那样。


然后引擎创造了另一个叫 throwaway(一次性)的 promise。 之所以被称为一次性,是因为它不会由任何链式绑定 - 它完全存在引擎内部。 然后 throwaway 会被链接到 promise 上,使用适当的处理程序来恢复异步函数。 这个 performPromiseThen 操作是 Promise.prototype.then() 隐式执行的。 最后,异步函数的执行会暂停,并将控制权返回给调用者。

调用程序会继续执行,直到调用栈为空。 然后 JavaScript 引擎开始运行 microtask:它会先运行之前的 PromiseResolveThenableJob,生成新的 PromiseReactionJob 以将 promise 链接到传递给 await 的值。 然后,引擎返回处理 microtask 队列,因为在继续主事件循环之前必须清空 microtask 队列。

接下来是 PromiseReactionJob,它用我们 await 的 promise 返回的值 - 此时是 42 - 完成了 promise,并将该反应处理到 throwaway 上。 然后引擎再次返回 microtask 循环,循环中是最终待处理的 microtask。


最新评论

  • 三相电源断零线,为什么会接二连三烧坏电器
  • 风力发电机转那么慢,一圈能发多少电?
  • 零线不带电,为什么还要拉一条?直接用地做
  • 电磁阀基础知识详解:原理、维护、选型
  • 新能源汽车DC/DC变换器及实物拆机图

QQ|门户地图|网站地图|家电维修|手机版|家电维修技术论坛 ( 蜀ICP备14030498号-16 川公网安备51102502000162号 )

GMT+8, 2025-5-23 18:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部