Async/ожидание собственных реализаций

Это предложение предполагает, что функции 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 function, который предлагается предложением и обычно реализуется в Babel и TypeScript?

Ответ 1

Как именно async/await работает в существующих нативных реализациях?

Если мы посмотрим на фактическую нативную реализацию async await в v8, мы ясно увидим и обещание, и генератор как очевидную основу реализации async-await, также в синтаксическом анализаторе он ясно указывает на природу обещания генератора для отладки async-await.

Что касается спецификации ES, то, хотя в спецификации напрямую не упоминается фактическая реализация переключения контекста выполнения, она намекает на использование того же Perform ! Call(promiseCapability.[[Resolve]] Perform ! Call(promiseCapability.[[Resolve]] который использует Promise.resolve. Таким образом, субъективно намекает на возможный "механизм" для обработки переключения контекста выполнения asyncContext.

Более того, когда прототип генератора становится испорченным в Chrome/Node.js, асинхронные функции, похоже, не затрагиваются, это говорит о том, что GeneratorFunction не используется AsyncFunction, по крайней мере, напрямую:

И generator и async функции во время выполнения являются потомками объекта Function, они не наследуются друг от друга, поэтому вы не видите зафиксированные изменения.

Но фактическая реализация собственного уровня конкретного объекта или метода необязательно должна быть связана с выполнением во время выполнения скомпилированных аналогов и их зависимостей, так же, как вы не можете изменить возможность вызова Function.prototype.call =() => {} путем переназначения Function.prototype.call =() => {}, так как %call% является реализацией собственного уровня.

Являются ли реализации более производительными, чем это было бы возможно с подходом Promise/generator, который предлагается в предложении и обычно реализуется в Babel и TypeScript?

Это зависит от движка js и реализованных оптимизаций и деоптимизаций на уровне компиляции, но подвержено постоянным изменениям, иногда собственная реализация медленнее, чем сторонняя реализация lib, как это было с map, forEach es5, аналогами map, forEach и lodash, но в большинстве случаев нативной реализация уровня не имеет себе равных из-за того, что на один уровень ближе к машинному коду. В качестве примера можно привести 2-кратную распространенность асинхронного ожидания в jsbench с асинхронным ожиданием по сравнению с регенератором вавилона по сравнению с обещанием.

Ответ 2

Насколько я знаю, функции генератора используются для имитации поведения async/await. Когда вы используете typescript, он будет скомпилирован в javascript, и в зависимости от вашей установки он скомпилирует синтаксис async/await для реализации генератора.

Подробнее о компиляции здесь: https://basarat.gitbooks.io/typescript/docs/async-await.html

Поэтому вы не должны беспокоиться об использовании их в typescript вообще, я думаю.

Я предполагаю, что встроенная реализация не использует генераторы, она должна быть в основном просто синтаксическим сахаром для работы с promises.