Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

javascript - async/await native implementations

This proposal suggests that async functions can use generator functions under the hood, although I cannot find a confirmation of this in ES2017 spec.

Moreover, when generator prototype becomes messed up in Chrome/Node.js, async functions don't seem to be affected, this suggests that GeneratorFunction isn't used by AsyncFunction, at least directly:

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

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

How exactly does async/await work in existing native implementations?

Are the implementations more performant than it would be possible with Promise/generator function approach that is suggested by the proposal and is usually implemented in Babel and TypeScript?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

How exactly does async/await work in existing native implementations?

If we look at the actual native implementation of async await in v8 we can clearly see both promise and generator as the obvious basis of async-await implementation, also in the parser it clearly states the generator-promise nature of desugaring async-await.

Regarding ES spec, even though the spec doesn't directly mention the actual implementation of execution context switching, it hints usage of same Perform ! Call(promiseCapability.[[Resolve]] mechanism the Promise.resolve is using. Thus subjectively hinting the possible "mechanism" to handle running execution context toggling of asyncContext.

Moreover, when generator prototype becomes messed up in Chrome/Node.js, async functions don't seem to be affected, this suggests that GeneratorFunction isn't used by AsyncFunction, at least directly:

Both generator and async functions in the runtime are descendants of the Function object, they don't inherit from one another though, that's why you don't see the committed changes.

But the actual native level implementation of specific host object or method doesn't have to necessarily be connected to runtime execution of compiled counterparts and their dependencies, the same way as you cannot alter the function's ability to be called by reassigning Function.prototype.call = () => {}, since %call% is a native level implementation.

Are the implementations more performant than it would be possible with Promise/generator function approach that is suggested by the proposal and is usually implemented in Babel and TypeScript?

It depends on js engine and its implemented compilation level optimizations and deoptimizations, but it's subject to continuous change, sometimes native implementation is slower than the 3rd party lib implementation, like it happened with es5 map, forEach vs lodash counterparts, but in most cases native level implementation is unmatched due to being one level closer to machine code. As an example here is the 2x prevalence of async-await in jsbench with async-await vs babel regenerator vs promise.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...