Работаем с асинхронной итерацией в ECMAScript 2019, используя for-of
Это очень понятное и доступное руководство по асинхронным итерациям в JavaScript. Сейчас этот подход наиболее актуален, так как можно избежать использования “прожорливого” Promise.All()
и кучи писанины с колбэками и лишними библиотеками.
Перевод статьи Working With ECMAScript 2019 Asynchronous Iteration Using “for-of”
👉Мой Твиттер — там много из мира фронтенда, да и вообще поговорим🖖. Подписывайтесь, будет интересно: ) ✈️
В этой статье упор делается на концепцию асинхронной итерации, которая стала доступна в ECMAScript 2019. Цикл for-of
зачастую используется для перебора списка элементов внутри цикла. И уже сейчас мы можем использовать for-of
в JavaScript, чтобы пробежаться по списку промисов и получить значение, которое отдастся при завершении работы каждого промиса.
Давайте проитерируем массив чисел, используя цикл for-of
:
Это довольно простой пример итерирования по списку employeeSalaries
. В этом случае код синхронно пробегается по данным. Каждое итерируемое значение представляет собой какие-либо данные, в нашем случае это простые числа.
Создаем простой промис
Ниже мы простым способом создаем промис в JavaScript:
Выше мы создаем простой промис, который берёт функцию с resolve
и reject
как параметрами ввода. Функция затем завершает промис после 2 секунд. Таким образом, объект newPromise
служит неким источником асинхронных данных.
Пробегаемся по массиву промисов с помощью “for-of”
А теперь, давайте представим, что у нас есть целый массив промисов и пользователь пробегается по списку этих самых промисов с помощью цикла “for-of
”. Что вы думаете будет выдано при каждой итерации? Давайте посмотрим на этом примере:
Код выше имеет список промисов внутри массива arrayOfPromise
. Теперь, давайте проитерируемся по всем элементам в массиве и выведем в консоль каждый из них:
В данном случае вывод будет таким:
Возвращение решенного значения при итерации с помощью for-of
Итерации выше выводят в консоль каждый объект промиса. Мы бы хотели улучшить такой функционал, поэтому во время итерирования по списку промисов, выводящееся значение должно быть решенным результатом каждого промиса, а не самим промисом.
Чтобы угодить этим требованиям, мы можем применить await
с циклом for-of
, чтобы пробежаться по каждому промису. Тогда мы сможем подождать пока промисы будут решены и уже потом выводить их результаты в консоль.
Вывод для кода выше будет таким:
Теперь выводятся решенные значения промисов, а не сами их объекты. Так происходит из-за того, что await прикреплен к for-of
.
Такая фича может быть полезной, когда у вас есть список промисов. Теперь нам не надо писать колбэки для каждой промис функции внутри списка промисов. Полученное решение это решенное значение для каждого промиса.
Порядок промисов в массиве
Другая важная вещь которую обязательно нужно рассмотреть — порядок вывода будет такой же, как и порядок промисов в массиве. Давайте посмотрим на это дело в действии, с помощью ещё одного примера:
В коде выше у нас есть список промисов, который ожидает своего решения. Первый промис в списке ждет 10 секунд, в то время, как другие промисы ожидают по три и две секунды каждый. Каков будет порядок выполнения в этом случае?
Вывод будет таким же, даже несмотря на то, что первый промис в списке требует для своего решения самое большое количество времени. В это время другие промисы будут решены, но вывод цикла for-of
всегда следует одной последовательности, а именной той, в которой они упомянуты в массиве промисов. PromiseTwo
и PromiseThree
в этом случае будут решены перед PromiseOne
, но они будут ждать решение первого промиса в списке, чтобы завершить цикл.