Bezdepbonusu7Программирование: статьи и ответы

Async/Await внутри массива и объекта

Архив Bezdepbonusu73 мин чтения

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

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

Код будет ждать получения результата от getA() перед вызовом getB() и так далее, но поскольку нам не нужно a для получения b или c, это пустая трата времени. Мы хотим получить все необходимое как можно скорее!

Вот почему Promise.all([...]) существует. И если эта статья не является учебным пособием по этому поводу, скажем так, что она вызывает все обещания, указанные в массиве, и возвращает обещание, которое разрешается только тогда, когда все данные обещания разрешаются.
Что здесь интересно, так это то, что это не не ждать разрешения каждого промиса перед вызовом следующего, как в нашем предыдущем примере. Он запускает их все и дает нам возможность узнать, когда все будет готово (возвращая все результаты):

Объявление объекта и массива

Но мы можем спросить себя: "Что произойдет, если мы ожидаем промисов внутри массива или объявления объекта?"

Будет ли разрешение промисов работать как в первом последовательном примере или как в примере Promise.all([...])?

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

Проблемы с Promise.all()

Итак, нам нужно использовать Promise.all([...]) , но у меня возникают проблемы с этим решением, когда количество промисов увеличивается, например:

Только представьте, если бы константы и методы были названы не как a, b и getA(), getB(), а скорее как monthlyStatistics, filteredStatistics, обе (или даже больше) вызывали бы одну и ту же функцию возврата промисов getStats(start, end, filters).

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

Говоря о подсказках типов, если вы используете Typescript с текущей версией VSCode (1.58.2, когда я пишу это), вы заметите, что файл lib.es2015.promise.d.ts "только" набирает до 10 промисов внутри массива, переданного Promise.all([...]) (таким образом, несмотря на метод не имеет такого низкого ограничения), что приводит к ошибке типа, если вы пытаетесь получить результаты "кортежным способом", как в предыдущем примере кода.

Окончательное решение

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

"Разве это не запустит код промисов дважды?" Нет, не будет, потому что мы запускаем методы создания промисов только один раз, а затем дважды ждем результата промисов. Сначала в Promise.all([...]), который мы знаем, запустим весь код промисов "одновременно", а затем во второй раз в назначении объекта мы ожидаем для каждого результата последовательно, но поскольку все промисы уже разрешены, результаты доступны в памяти и почти сразу вернулся.

Если хотите убедиться в этом, не верьте моим словам (но мой код ;-)):

Вывод

Это не обширная документация, а напоминание самому себе, которое может быть (или не быть) полезным для других.

В этом отношении, пожалуйста, сообщите мне, если что-то не так, и не стесняйтесь делиться своими мыслями о конечном результате или о вашем собственном другом методе :-)

(Так как это мой первый пост на Medium в качестве человека, для которого английский язык не является родным, сообщите мне, если заметите опечатку или я нарушил секретное правило сообщества ;-))

Спасибо за чтение !

AsynchronousJavaScriptTypescript

Похожие материалы

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