Работаем с асинхронной итерацией в ECMAScript 2019, используя for-of

Stas Bagretsov
4 min readAug 20, 2019

--

Это очень понятное и доступное руководство по асинхронным итерациям в 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, но они будут ждать решение первого промиса в списке, чтобы завершить цикл.

--

--

Stas Bagretsov

Надеюсь верую вовеки не придет ко мне позорное благоразумие. webdev/sports/books