[Перевод] async-await≈генераторы + промисы

внешний интерфейс Promise ECMAScript 6

Async-Await ≈ Генераторы + Промисы

В этой статье я представлюES2017изasyncПочему функцияES2016изGeneratorsа такжеPromisesСинтаксический сахар для функций функций.

Чтение инструкций

  • В этой статье не вводятся и не объясняются три понятия
  • Единственная цель этой статьи — описать, как использоватьGeneratorsа такжеPromisesреализоватьasync
  • Эта статья оasyncи другие подобные реализации не оцениваются на предмет плюсов и минусов
  • Коды в этой статье умно разработаны для легкого понимания, они не подходят для реальной разработки.

Зачем?

теперь, когдаasyncФункция нативно поддерживается, надо разбираться как она работает?

Что ж, помимо любопытства о том, как это работает, важнее поддерживать старые платформы. Если вы хотите, чтобы код, использующий новые функции, работал в старых версиях браузера иNode.jsверсия, вам может понадобиться использовать что-то вродеBabelТакой инструмент для преобразования этих новых функций.

Поэтому глубокое пониманиеasyncКак функции разлагаются наgeneratorsа такжеpromisesПозже это может быть очень полезно при чтении или отладке преобразованного кода. Например, это простойasyncфункция:

одеялоBabelПеревести вES2016Код выглядит следующим образом (не совсем понял его, он будет объяснен ниже):

Разница была велика! Конечно, если вы понимаетеasyncработает, то этот преобразованный код вам не составит труда.

Еще один интересный факт заключается в том, что браузеры такжеasyncФункция для реализации: как в браузереBabelиспользовать то же самоеgeneratorsа такжеpromisesидтиконвертироватьasync.

Так что именно произошло?

Иногда лучший способ понять, как что-то работает, — это сделать это самому.

Например, у нас есть раздел, использующийasyncФрагмент кода функции, как мы можем воспользоватьсяgeneratorsа такжеpromisesпереписать его?

это нашеasyncфункция:

В теле функции последовательно выполняются три асинхронные задачи, и каждая задача зависит от завершения предыдущей задачи. Наконец, функция возвращает результат последней задачи.

как использоватьgeneratorsпереписать

Функция генератора такова: можно выйти и снова войти.让我们快速回顾一下它的工作方式,以下是一个简单的generatorфункция:

эта генераторная функцияgenимеет некоторые интересные особенности (отMDNизвлекать):

  1. когдаgeneratorФункция вызывается, а код внутри функции нене выполняется сразу. Он возвращает последовательныйпротокол итератораиз迭代器объект: он имеетnextметод
  2. воплощать в жизньgenЕдинственный способ для кодирования внутри функции находится в возврате迭代器вызов на объектnextметод. каждый звонокnext, код в теле функции выполняется доyieldвыражение, выражение右值назначить на迭代器.
  3. nextМетоды также могут принимать параметры, вызов с параметрами заменит предыдущий вызов значением параметра.yieldвыразительный左值А затем выполнить и вернуть текущийyieldвыразительный右值
const a = yiled foo();
//    |           |
//    |           |
//   左值         右值

Пожалуйста, внимательно ознакомьтесь с приведенными выше шагами или обратитесь кДокументация MDN.

Как эти функции помогают нам?

К настоящему времени вы, возможно, задаетесь вопросом,generatorКак функция выражает цель этой статьи?

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

Но до сих пор все, что мы обсуждали, было синхронным. Как сделать?

Примечание переводчика: вышеизложенноеyieldВыражения сопровождаются синхронизированными значениями

Функция генератора ключей может бытьpromisesпровестиyield

ОдинgeneratorФункция можетpromiseпровестиyield, и это迭代器Можно управлять, чтобы остановиться и подождатьpromiseнаконецresolveилиrejectИ переходим к следующему шагу со значением их разрешения. Эта конструкция можетyield promisesШаблон итератора для удовлетворения наших потребностей:

Notice how this generator function resembles our async function!

Мы только на полпути так далеко. Нам нужен метод, который выполняет содержимое функционального тела, нам нужен метод, который может контролироватьgeneratorфункция迭代器функция, которая останавливается и ждет каждогоyield promiseрезультат решения. Это звучит сложно, но это довольно просто реализовать:

A function that executes a generator function. (Only for explanation, do not use it !)

Теперь мы можем использовать его, как показано ниже.runnerфункция выполняет нашу функцию генератораinit:

Use `runner` to execute the body of `init`.

Это так просто!runnerфункция иinitКомбинированное использование функций достигает нативного уровняasyncэффект функции.

Пожалуйста, помните этоrunnerФункция представляет собой просто демонстрационный код для объяснения цели этой статьи, она не подходит для реальных сценариев разработки, если вам нужна подходящая реализация, вы можетездесьСмотреть.

Суммировать

мы начинаем сasyncфункцию, а затем использоватьgeneratorsа такжеpromisesДля достижения той же функции:

Углубленная практика

  • В начале этой статьи мы видимBabelБудуES2017изasyncПосле преобразования функции, как использоватьES2016изgeneratorsа такжеpromisesдостигать. Вы можете посмотреть перед преобразованием после_asyncToGeneratorфункции, сравните нашиrunner函数就会发现两者很相似。 Фактически,_asyncToGeneratorФункция у нас тут предельно простаяrunnerНадежная версия функции

  • Если вы все еще заинтересованы, вы можете выполнить следующий шаг исследования, который заключается в том, чтобы поставитьasyncфункция преобразуется в нетgeneratorsизES2015Версия кода. Поэтому вам может понадобиться смоделироватьgeneratorsсебя (см.regenerator project)

Я надеюсь ткать через эту статьюasyncТуман функций, обеспечивающий простой синтаксис и уменьшающий шум кода.asyncПредложение функции описывается следующим образом:

The introduction of Promises and Generators in ECMAScript presents an opportunity to dramatically improve the language-level model for writing asynchronous code in ECMAScript.

благодарныйAkos, Alisaтак же какKristianОтзыв, предоставленный для улучшения этой статьи.