Что такое async await

Async/await

Существует специальный синтаксис для работы с промисами, который называется «async/await». Он удивительно прост для понимания и использования.

Асинхронные функции

У слова async один простой смысл: эта функция всегда возвращает промис. Значения других типов оборачиваются в завершившийся успешно промис автоматически.

Например, эта функция возвратит выполненный промис с результатом 1 :

Можно и явно вернуть промис, результат будет одинаковым:

Await

Ключевое слово await заставит интерпретатор JavaScript ждать до тех пор, пока промис справа от await не выполнится. После чего оно вернёт его результат, и выполнение кода продолжится.

В этом примере промис успешно выполнится через 1 секунду:

В данном примере выполнение функции остановится на строке (*) до тех пор, пока промис не выполнится. Это произойдёт через секунду после запуска функции. После чего в переменную result будет записан результат выполнения промиса, и браузер отобразит alert-окно «готово!».

Обратите внимание, хотя await и заставляет JavaScript дожидаться выполнения промиса, это не отнимает ресурсов процессора. Пока промис не выполнится, JS-движок может заниматься другими задачами: выполнять прочие скрипты, обрабатывать события и т.п.

Ошибки не будет, если мы укажем ключевое слово async перед объявлением функции. Как было сказано раньше, await можно использовать только внутри async –функций.

Давайте перепишем пример showAvatar() из раздела Цепочка промисов с помощью async/await :

Получилось очень просто и читаемо, правда? Гораздо лучше, чем раньше.

Можно обернуть этот код в анонимную async –функцию, тогда всё заработает:

В примере ниже, экземпляры класса Thenable будут работать вместе с await :

Для объявления асинхронного метода достаточно написать async перед именем:

Обработка ошибок

Делает то же самое, что и такой:

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

Так сделано в строке (*) в примере выше.

Итого

Ключевое слово async перед объявлением функции:

Ключевое слово await перед промисом заставит JavaScript дождаться его выполнения, после чего:

Вместе они предоставляют отличный каркас для написания асинхронного кода. Такой код легко и писать, и читать.

Источник

Async/await это шаг назад для JavaScript’a?

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

В конце 2015 года я услышал об этой паре ключевых слов, которые ворвались в мир JavaScript, чтобы спасти нас от promise chain hell, который, в свою очередь, должен был спасти нас от callback hell. Давайте посмотрим несколько примеров, чтобы понять, как мы дошли до async/await.

Допустим, мы работаем над нашим API и должны отвечать на запросы серией асинхронных операций:
— проверить валидность пользователя
— собрать данные из базы данных
— получить данные от внешнего сервиса
— изменить и записать данные обратно в базу данных

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

И это так называемый callback hell. Теперь вы знакомы с ним. Все его ненавидят, так как его трудно читать, отлаживать, изменять; он уходит все глубже и глубже во вложенности, обработка ошибок повторяется на каждому уровне и т.д.

Мы могли бы использовать знаменитую async библиотеку, чтобы немного очистить код. Код стал бы лучше, так как обработка ошибок, по крайней мере, была бы в одном месте:

Позже мы узнали как использовать промисы и подумали, что мир больше не злится на нас; мы почувствовали, что нужно провести рефакторинг кода еще раз, ведь все больше и больше библиотек также движется в мир промисов.

Это гораздо лучше, чем раньше, гораздо короче и намного чище! Тем не менее возникло слишком много накладных расходов в виде множества then() вызовов, function () <. >блоков и необходимости добавлять несколько операторов return повсюду.

И наконец мы слышим о ES6, обо всех этих новых вещах, которые пришли в JavaScript: например стрелочные функции (и немного деструктуризации, чтобы было чуть веселее). Мы решаем дать нашему прекрасному коду еще один шанс.

И вот оно! Этот обработчик запросов стал чистым, легкочитаемым. Мы понимаем что его легко изменить если нам нужно добавить, удалить или поменять местами что-то в потоке! Мы сформировали цепочку функций, которые одна за другой мутируют данные, которые мы собираем с помощью различных асинхронных операций. Мы не определяли промежуточные переменные для хранения этого состояния, а обработка ошибок находится в одном понятном месте. Теперь мы уверены, что определенно достигли JavaScript высот! Или еще нет?

И приходит async/await

Несколько месяцев спустя async/await выходит на сцену. Он собирался попасть в спецификацию ES7, затем идею отложили, но т.к. есть Babel, мы прыгнули в поезд. Мы узнали, что можем отметить функцию как асинхронную и что это ключевое слово позволит нам внутри функции «остановить» ее поток исполнения до тех пор, пока промис не решит, что наш код снова выглядит синхронным. Кроме того, функция async всегда будет возвращать промис, и мы можем использовать try/catch блоки для обработки ошибок.

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

И теперь код снова выглядит как старый обычный императивный синхронный код. Жизнь продолжилась как обычно, но что-то глубоко в вашей голове говорит нам что что-то здесь не так…

Функциональная парадигма программирования

Хотя функциональное программирование было вокруг нас в течение более чем 40 лет, похоже что совсем недавно парадигма стала набирать обороты. И лишь в последнее время мы стали понимать преимущества функционального подхода.

Мы начинаем обучение некоторым из его принципов. Изучаем новые слова, такие как функторы, монады, моноиды — и вдруг наши dev-друзья начинают считать нас крутыми, потому что мы используем эти странные слова довольно часто!

Мы продолжаем свое плавание в море функциональной парадигмы программирования и начинаем видеть ее реальную ценность. Эти сторонники функционального программирования не были просто сумасшедшими. Они были, возможно, правы!

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

Но… постойте!

Мы видели все эти функциональные модели в прошлом. Мы помним, как мы использовали обещания и как соединяли функциональные преобразования один за другим без необходимости управлять состоянием или ветвить наш код или управлять ошибками в императивном стиле. Мы уже использовали promise-монаду в прошлом со всеми сопутствующими преимуществами, но в то время мы просто не знали это слово!

И мы вдруг понимаем, почему код на основе async/await смотрелся странно. Ведь мы писали обычный императивный код, как в 80-х годах; обрабатывали ошибки с try/catch, как в 90-х годах; управляли внутренним состоянием и переменными, делая асинхронные операции с помощью кода, который выглядит как синхронный, но который внезапно останавливается, а затем автоматически продолжает выполнение когда асинхронная операция будет завершена (когнитивный диссонанс?).

Последние мысли

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

Но если вы любите промисы и хотите научиться применять все больше и больше функциональных принципов программирования, вы можете просто пропустить async/await, перестать думать императивно и перейти к новой-старой функциональной парадигме.

Источник

Разбираем Async/Await в JavaScript на примерах

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

Автор статьи разбирает на примерах Async/Await в JavaScript. В целом, Async/Await — удобный способ написания асинхронного кода. До появления этой возможности подобный код писали с использованием коллбэков и промисов. Автор оригинальной статьи раскрывает преимущества Async/Await, разбирая различные примеры.

Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».

Skillbox рекомендует: Образовательный онлайн-курс «Java-разработчик».

Callback

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

Вот пример асинхронного чтения файла на Node.js:

Проблемы возникают в тот момент, когда требуется выполнить сразу несколько асинхронных операций. Давайте представим себе вот такой сценарий: выполняется запрос в БД пользователя Arfat, нужно считать его поле profile_img_url и загрузить картинку с сервера someserver.com.
После загрузки конвертируем изображение в иной формат, например из PNG в JPEG. Если конвертация прошла успешно, на почту пользователя отправляется письмо. Далее информация о событии заносится в файл transformations.log с указанием даты.

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

Стоит обратить внимание на наложенность обратных вызовов и большое количество >) в финальной части кода. Это называется Callback Hell или Pyramid of Doom.

Недостатки такого способа очевидны:

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

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

Предположим, что есть цикл for, выводящий последовательность чисел от 0 до 10 со случайным интервалом (0–n секунд). Используя промисы, нужно изменить этот цикл таким образом, чтобы числа выводились в последовательности от 0 до 10. Так, если вывод нуля занимает 6 секунд, а единицы — 2 секунды, сначала должен быть выведен ноль, а потом уже начнется отсчет вывода единицы.

Async-функции

Добавление async-функций в ES2017 (ES8) упростило задачу работы с промисами. Отмечу, что async-функции работают «поверх» промисов. Эти функции не представляют собой качественно другие концепции. Async-функции задумывались как альтернатива коду, который использует промисы.

Async/Await дает возможность организовать работу с асинхронным кодом в синхронном стиле.

Таким образом, знание промисов облегчает понимание принципов Async/Await.

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

Async вставляется в самом начале объявления функции, а в случае использования стрелочной функции — между знаком «=» и скобками.

Эти функции можно поместить в объект в качестве методов либо же использовать в объявлении класса.

NB! Стоит помнить, что конструкторы класса и геттеры/сеттеры не могут быть асинхронными.

Семантика и правила выполнения

Async-функции, в принципе, похожи на стандартные JS-функции, но есть и исключения.

Так, async-функции всегда возвращают промисы:

В частности, fn возвращает строку hello. Ну а поскольку это асинхронная функция, то значение строки обертывается в промис при помощи конструктора.

Вот альтернативная конструкция без Async:

В этом случае возвращение промиса производится «вручную». Асинхронная функция всегда обертывается в новый промис.

В том случае, если возвращаемое значение — примитив, async-функция выполняет возврат значения, обертывая его в промис. В том случае, если возвращаемое значение и есть объект промиса, его решение возвращается в новом промисе.

Но что произойдет в том случае, если внутри асинхронной функции окажется ошибка?

Если она не будет обработана, foo() вернет промис с реджектом. В этой ситуации вместо Promise.resolve вернется Promise.reject, содержащий ошибку.

Async-функции на выходе всегда дают промис, вне зависимости от того, что возвращается.

Await влияет на выражения. Так, если выражение является промисом, async-функция приостанавливается до момента выполнения промиса. В том случае, если выражение не является промисом, оно конвертируется в промис через Promise.resolve и потом завершается.

А вот описание того, как работает fn-функция.

Решаем задачу

Ну а теперь давайте рассмотрим решение задачи, которая была указана выше.

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

Вот решение с выводом чисел, здесь есть два варианта.

А вот решение с использованием async-функций.

Необработанные ошибки обертываются в rejected промис. Тем не менее в async-функциях можно использовать конструкцию try/catch для того, чтобы выполнить синхронную обработку ошибок.

canRejectOrReturn() — это асинхронная функция, которая либо удачно выполняется (“perfect number”), либо неудачно завершается с ошибкой (“Sorry, number too big”).

Поскольку в примере выше ожидается выполнение canRejectOrReturn, то собственное неудачное завершение повлечет за собой исполнение блока catch. В результате функция foo завершится либо с undefined (когда в блоке try ничего не возвращается), либо с error caught. В итоге у этой функции не будет неудачного завершения, поскольку try/catch займется обработкой самой функции foo.

Стоит уделить внимание тому, что в примере из foo возвращается canRejectOrReturn. Foo в этом случае завершается либо perfect number, либо возвращается ошибка Error (“Sorry, number too big”). Блок catch никогда не будет исполняться.

Проблема в том, что foo возвращает промис, переданный от canRejectOrReturn. Поэтому решение функции foo становится решением для canRejectOrReturn. В этом случае код будет состоять всего из двух строк:

А вот что будет, если использовать вместе await и return:

В коде выше foo удачно завершится как с perfect number, так и с error caught. Здесь отказов не будет. Но foo завершится с canRejectOrReturn, а не с undefined. Давайте убедимся в этом, убрав строку return await canRejectOrReturn():

Распространенные ошибки и подводные камни

В некоторых случаях использование Async/Await может приводить к ошибкам.

Такое случается достаточно часто — перед промисом забывается ключевое слово await:

В коде, как видно, нет ни await, ни return. Поэтому foo всегда завершается с undefined без задержки в 1 секунду. Но промис будет выполняться. Если же он выдает ошибку или реджект, то в этом случае будет вызываться UnhandledPromiseRejectionWarning.

Async-функции в обратных вызовах

Нам нужны аккаунты ArfatSalman, octocat, norvig. В этом случае выполняем:

Чрезмерно последовательное использование await

В качестве примера возьмем такой код:

Здесь в переменную count помещается число репо, затем это число добавляется в массив counts. Проблема кода в том, что пока с сервера не придут данные первого пользователя, все последующие пользователи будут находиться в режиме ожидания. Таким образом, в единый момент обрабатывается лишь один пользователь.

Promise.all на входе получает массив промисов с возвращением промиса. Последний после завершения всех промисов в массиве или при первом реджекте завершается. Может случиться так, что все они не запустятся одновременно, — для того чтобы обеспечить одновременный запуск, можно использовать p-map.

Заключение

Async-функции становятся все более важными для разработки. Ну а для адаптивного использования async-функций стоит воспользоваться Async Iterators. JavaScript-разработчик должен хорошо разбираться в этом.

Источник

Осваиваем async/await на реальном примере

Конструкция async/await представляет собой сравнительно новый подход к написанию асинхронного кода в JavaScript. Она основана на промисах и, в результате, не блокирует главный поток. Новшество этой конструкции заключается в том, что благодаря ей асинхронный код становится похожим на синхронный и ведёт себя подобным образом. Это открывает перед программистом замечательные возможности.

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

До появления async/await при разработке асинхронных механизмов программ использовались коллбэки и промисы. Автор материала, перевод которого мы публикуем сегодня, предлагает сначала вспомнить о том, как писать код по-старому, а потом, на реальном примере, изучить применение async/await.

Коллбэки

Вот как выглядит пример кода, в котором используются коллбэки (функции обратного вызова):

При использовании вложенных функций обратного вызова возникает проблема, называемая «адом коллбэков». Вот упрощённый пример кода, иллюстрирующий эту проблему:

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

Промисы

Вот пример кода, в котором используются промисы (Promise-объекты):

Асинхронные функции

Функции, объявленные с использованием ключевого слова async (асинхронные функции), дают нам возможность писать аккуратный и не перегруженный служебными конструкциями код, позволяющий получить тот же результат, который мы получали с использованием промисов. Надо отметить, что ключевое слово async — это, в сущности, лишь «синтаксический сахар» для промисов.

Сравним работу асинхронной функции и промиса, которые возвращают строку:

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

Теперь, когда мы рассмотрели базовые вещи, перейдём к нашему примеру.

Конвертер валют

▍Предварительная подготовка

Здесь мы создадим простое, но познавательное с точки зрения изучения конструкции async/await приложение. Оно представляет собой конвертер валют, который использует реальные данные, получаемые из соответствующих API. Программа принимает сумму в некоей валюте, код этой валюты, а также код валюты, в которую мы хотим конвертировать эту сумму. После этого программа выводит результат, предварительно загрузив актуальные данные по курсам валют. Программа также выводит список стран, в которых можно потратить деньги в той валюте, в которую осуществляется перевод заданной суммы.

В частности, здесь мы собираемся пользоваться данными из двух асинхронных источников информации:

Приступим к написанию кода программы, подключив в этом файле Axios:

В нашем проекте будет три асинхронные функции. Первая будет загружать данные о валютах. Вторая будет загружать данные о странах. Третья будет эти данные собирать, представлять в удобном для пользователя виде и выводить на экран.

▍Первая функция — асинхронная загрузка данных о валютах

В этой функции нам надо загрузить данные. Благодаря использованию конструкции async/await можно записывать полученные данные непосредственно в некую переменную или константу. Перед написанием кода этой функции не забудьте зарегистрироваться на сайте и получить ключ доступа к API. Для загрузки данных нам понадобится следующая конструкция:

Поместим объект с курсами валют в константу rate :

Обратите внимание на то, что для обработки ошибок, которые могут возникнуть в ходе выполнения запроса, используется обычная конструкция try/catch.

▍Вторая функция — асинхронная загрузка данных о странах

Для загрузки данных мы пользуемся следующей командой:

Если, например, мы используем в запросе код HRK (хорватская куна), то в ответ нам придёт JSON-код, фрагмент которого показан ниже:

Вот как выглядит полный код функции getCountries() :

▍Третья функция — сбор и вывод данных

В ней мы сначала получаем обменный курс:

Потом загружаем список стран:

Далее — выполняем конверсию:

А после того, как все необходимые данные собраны — возвращаем строку, которую увидит пользователь программы:

Вот полный код функции:

Обратите внимание на то, что в этой функции нет блока try/catch, так как она работает лишь с результатами, предоставленными ей двумя ранее описанными функциями.

▍Запуск программы

Здесь мы хотим выяснить — на сколько хорватских кун можно обменять 20 евро и попутно узнать о том, в каких странах можно эти деньги потратить.

Вызовем программу, введя в терминале следующую команду:

В ответ мы получим примерно следующее.

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

Результат работы программы

Вот, на всякий случай, полный код нашего проекта.

Итоги

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

Уважаемые читатели! Если вы используете на практике конструкцию async/await — просим поделиться впечатлениями о ней.

Источник

Async/Await в javascript. Взгляд со стороны

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

В последнее время все больше моих друзей, коллег и людей из сообщества говорят про работу с асинхронными функциями и в частности про использование async/await на своих проектах. Я решил разобраться для себя, что это за зверь и стоит ли его использоваться при разработке боевых проектов.

Первое что хочется развеять, это распространенное заблуждение о том, что async/await — это фича ES7.

По моему мнению, использование терминов ES6 и ES7 само по себе не очень верное и может ввести разработчиков в заблуждение. После удачного релиза спецификации ES2015, называемой ES6, у многих людей сложилось ошибочное мнение, что все в нее не вошло и заполифилено через babel — это фичи ES7. Это не так. Вот список того что появится с релизом спецификации ES2016. Как видите он не такой большой и async/await в нем никак не значится.

Я хочу, чтобы мы говорили правильно. И говоря о той, или иной фиче, ссылались на конкретную спецификацию в рамках которой она описана и реализована, а не мифические ES6, ES7 … ESN.

Двигаемся дальше. Так что же такое async/await простыми словами?

Говоря общедоступным языком async/await — это Promise.

Когда вы объявляете функцию как асинхронную, через волшебное слово async, вы говорите, что данная функция возвращает Promise. Каждая вещь которую вы ожидаете внутри этой функции, используя волшебное слово await, то же возвращает Promise.

Это очень важный момент для понимания, как такие функции работают и чего ожидать при работе с ними.

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

Вот простой пример асинхронного Redux экшена для выхода из кабинета:

А теперь идем от общего к частному

После прочтения ряда статей и самостоятельно поигравшись, я составил для себя небольшой бриф, отвечающий на основные вопросы, с небольшими примерами.

Что нужно сделать чтобы начать работу?

Если не использовать никакой системы сборки, то достаточно установить babel и babel-runtime.

В остальных случаях, лучше смотреть настройки исходя их системы сборки и версии babel. Это очень важно, так как настройки в версии babel5 и babel6 сильно различаются.

Как создается асинхронная функция?

Создание асинхронной функции состоит из двух основных частей:

1. Использования слова async перед объявлением функции.

Как мы видим из примера c logout(), это так же работает при использовании стрелочных функций. Еще это работает для функций классов и статичных функций. В последнем случае async пишется после static.

2. В теле самой функции мы должны использовать слово await.

Использование слова await сигнализирует о том, что бы основной код ждал и не возвращал ответ, пока не выполниться какое-то действие. Оно просто обрабатывает Promise для нас и ждет пока он вернет resolve или reject. Таким образом, создается впечатление, что код выполняется синхронно.

* Для работы с await функция должна быть асинхронной и объявлена с помощью ключевого слова async. В противном случае это просто не будет работать.

Как работает await и какую функцию выполняет?

Так как код в синхронном стиле, по этой причине мы можем использовать старый добрый try/catch для решения подобных задач.

Дополнительно хочется акцентировать на этом внимание.

Что такое async await. Смотреть фото Что такое async await. Смотреть картинку Что такое async await. Картинка про Что такое async await. Фото Что такое async await

Использование try/catch это единственный способ поймать и обработать ошибку. Если по каким-то причинам вы решите его не использовать или просто забыли, это может привести к отсутствию возможности обработки, а так же потере вовсе.

В какой момент происходит выполнение кода следующего за await?

Код следующий после await, продолжает свое выполнение только тогда когда функция используемая с await вернет resolve или reject.

Что если функция используемая с await не возвращает Promise?

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

Что если объявить функцию асинхронной, но не использовать await?

В таком случае, на выходе мы получим просто ссылку на Promise функции getRainbow().

Что будет если я напишу несколько функций использующих await подряд?

Такой код будет выполняться последовательно. Сначала отработает getRainbow(), после того как она вернет resolve или reject начнет работать getFood(). Один вызов, один результат.

А если мне нужно одновременно получить результат от нескольких вызовов?

Дополнительно хочу заметить, что конструкция await * arrayOfPromises больше не актуальна и удалена из спецификации. При попытке ее использовать вы по получите сообщение с любовью о том, что лучше использовать Promise.all().

Обновил информацию по конструкции await*. Спасибо xGromMx и degorov.

Что еще хорошо бы знать для успешной работы?

Надо помнить, что если ты начинаешь использовать async/await в своем проекте, нужно быть готовым к тому, что почти весь твой стек должен будет быть асинхронным. А это может добавить не мало проблем и неудобств.

С основными теоретическими аспектами мы разобрались, если что-то осталось непонятным или у Вас есть что дополнить, жду в комментариях.

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

Выводы:

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

Но это на первый взгляд.

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

Почти все вечно зеленые браузеры, из коробки, на 93%-98% поддерживают фичи ES2015 (таблица). Для меня это означает, что начиная новый проект, исходя из требований и стека, я уже задумаюсь об необходимости babel на проекте.

Но, если я решу использовать async/await, я буду обязан использовать babel. И не могу сказать что это добавит красоты в мой код. Ведь официально async/await нет, и не известно будет ли вообще. И это для меня большой минус.

Так же мне очень не нравится тот факт, что если я забыл применить await или просто не удачный копипаст, вместо автоматического вылета на ошибку, я ничего не получу, кроме ссылки на Promise. Это может быть черевато последствиями, особенно когда большой проект с несколькими разработчиками.

Большинство задач с использованием async/await прекрасно решаются с помощью генераторов.

Во-первых, у них и поддержка лучше.
Во-вторых, работа генераторов будет более естественна и предсказуема.
В-третьих сам babel приводит такой код к генераторам при особых настройках пример1, пример2.

Поддержка в NodeJS

Async/await уже экспериментально попал в V8. Это значит что с версии nodejs 7 можно с ним поиграться и поработать прямо из коробки.
Как это сделать:

Итого

Например мне понравилось использовать их в экшенах для Redux. Выглядит все красиво и гармонично.

Этот материал я писал в первую очередь для себя, чтобы разобраться с интересующим меня вопросом. Если данный материал будет еще кому-то полезен, я буду очень рад.

Также, в следующей статье, я бы хотел подробно сравнить разные подходы к реализации асинхронности (колбэки, промисы, генераторы, атомы). Чтобы это было понятно не только гуру, но и людям только начинающим свой путь в javascript.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *