异步/等待本机实现

Posted

技术标签:

【中文标题】异步/等待本机实现【英文标题】:async/await native implementations 【发布时间】:2018-04-05 03:15:40 【问题描述】:

This proposal 建议 async 函数可以在后台使用生成器函数,尽管我在 ES2017 规范中找不到对此的确认。

此外,当生成器原型在 Chrome/Node.js 中变得混乱时,async 函数似乎没有受到影响,这表明 GeneratorFunction 不被 AsyncFunction 使用,至少直接:

Object.getPrototypeOf((function * () ).prototype).next = null;

(async () => 
    return await Promise.resolve(1);
)()
.then(console.log);

async/await 在现有的本机实现中究竟是如何工作的?

这些实现是否比提案中建议的Promise/generator 函数方法的性能更高,并且通常在 Babel 和 TypeScript 中实现?

【问题讨论】:

我相信 async - await 使用的机制与 promise 完全相同,但编译器的解析方式不同。在他们的原生实现之前,可以通过使用生成器和 Promise 来获得类似于 async-await 的抽象(命令式异步代码)explained here beautifully。 【参考方案1】:

async/await 在现有的本机实现中究竟是如何工作的?

如果我们查看实际的native implementation of async await in v8,我们可以清楚地看到promise 和generator 都是async-await 实现的明显基础,同样在parser 中它清楚地说明了去糖async-await 的generator-promise 本质。

关于 ES 规范,尽管规范没有直接提及执行上下文切换的实际实现,但它暗示使用 Promise.resolve 正在使用的相同 Perform ! Call(promiseCapability.[[Resolve]] 机制。因此主观暗示了可能的“机制”来处理asyncContext的运行执行上下文切换。

此外,当生成器原型在 Chrome/Node.js 中变得混乱时,异步函数似乎没有受到影响,这表明 AsyncFunction 至少直接没有使用 GeneratorFunction:

运行时中的generatorasync 函数都是Function 对象的后代,但它们不会相互继承,这就是您看不到已提交更改的原因。

但特定宿主对象或方法的实际本机级别实现不一定要连接到已编译对应项及其依赖项的运行时执行,就像您不能通过重新分配 @987654333 来更改函数被调用的能力一样@,因为 %call% 是本机级别的实现。

这些实现是否比提案建议的 Promise/generator 函数方法可能实现的性能更高,并且通常在 Babel 和 TypeScript 中实现?

它取决于 js 引擎及其实现的编译级别优化和反优化,但它会不断变化,有时原生实现比 3rd 方 lib 实现慢,如it happened with es5 map, forEach vs lodash counterparts,但在大多数情况下原生实现是无与伦比的由于更接近机器代码一级。这里以 2x prevalence of async-await in jsbench with async-await vs babel regenerator vs promise 为例。

【讨论】:

jsperf 链接已失效 :( @ŁukaszGodziejewski 替换为 jsbench【参考方案2】:

据我所知,生成器函数用于模仿async/await 的行为。当您使用 typescript 时,它将被编译为 javascript,并且根据您的设置,它会将 async/await 语法编译到生成器实现中。

更多关于编译的信息:https://basarat.gitbooks.io/typescript/docs/async-await.html

所以我认为你根本不用担心在 typescript 中使用它们。

我猜原生实现不使用生成器,它应该基本上只是用于处理 Promise 的语法糖。

【讨论】:

是的,问题是关于本机实现(低级)。我想知道它们是否比生成器+承诺构造器更有效。

以上是关于异步/等待本机实现的主要内容,如果未能解决你的问题,请参考以下文章

如何在 api 调用中使用异步等待获取在反应本机中通过基本身份验证

Node.js mongodb 驱动程序异步/等待查询

使用 JNA 本机等待调用检测线程中断 (Windows)

.NET 的 WebBrowser 类的异步/等待实现

java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring Even

如何在c#中正确实现等待异步[重复]