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.
async - await
is using exactly the same mechanism with promises but parsed differently by the compiler. Before their native implementation one could get an abstraction (imperative looking asychronous code) similar to async-await by using generators and promises as explained here beautifully. – Laboured