Насколько я понимаю, в ES7 / ES2016 размещение нескольких await
кодов в коде будет работать подобно цепочке .then()
с обещаниями, то есть они будут выполняться один за другим, а не в parallerl. Так, например, у нас есть этот код:
await someCall();
await anotherCall();
Правильно ли я понимаю, что anotherCall()
будет вызываться только после someCall()
завершения? Каков самый элегантный способ их параллельного вызова?
Я хочу использовать его в Node, так что, возможно, есть решение с асинхронной библиотекой?
РЕДАКТИРОВАТЬ: Я не удовлетворен решением, предоставленным в этом вопросе: замедление из-за непараллельного ожидания обещаний в асинхронных генераторах , потому что он использует генераторы, и я спрашиваю о более общем случае использования.
javascript
node.js
asynchronous
ecmascript-6
babeljs
Виктор Марчук
источник
источник
await
будет ждать завершения первой функции полностью перед выполнением второго.Promise
s. Связанный вопрос касается библиотеки bluebird с генераторами и yield. Концептуально подобное возможно, но не в реализации.Ответы:
Вы можете ждать на
Promise.all()
:Для сохранения результатов:
Обратите внимание, что это происходит
Promise.all
быстро, что означает, что как только одно из обещаний, переданных ему, отклоняется, тогда все отклоняется.Если вместо этого вы хотите подождать, пока все обещания будут выполнены или отклонены, то вы можете использовать
Promise.allSettled
. Обратите внимание, что Internet Explorer изначально не поддерживает этот метод.источник
[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
ли это еще ?TL; DR
Используйте
Promise.all
для параллельных вызовов функций, поведение ответа не правильно, когда происходит ошибка.Сначала выполните все асинхронные вызовы одновременно и получите все
Promise
объекты. Во-вторых, использоватьawait
наPromise
объектах. Таким образом, пока вы ожидаете первого,Promise
чтобы разрешить другие асинхронные вызовы все еще продолжаются. В целом, вы будете ждать только самый медленный асинхронный вызов. Например:Пример JSbin: http://jsbin.com/xerifanima/edit?js,console
Предостережение: не имеет значения,
await
находятся ли вызовы на одной и той же линии или на разных линиях, при условии, что первыйawait
вызов происходит после всех асинхронных вызовов. Смотрите комментарий JohnnyHK.Обновить: этот ответ имеет различное время обработки ошибок в соответствии с ответом @ bergi , он НЕ выдает ошибку при возникновении ошибки, но после выполнения всех обещаний. Я сравниваю результат с подсказкой @ jonny:,
[result1, result2] = Promise.all([async1(), async2()])
проверьте следующий фрагмент кодаисточник
[someResult, anotherResult] = [await someResult, await anotherResult]
перейтиconst
наlet
.await
операторы последовательно, верно? То есть выполнение приостанавливается до тех пор, пока первое неawait
разрешится, затем перейдет ко второму.Promise.all
выполняется параллельно.Promise.all
. Если каждый запрос является сетевым вызовом,await someResult
его необходимо будет решить до того, как онawait anotherResult
будет запущен. И наоборот,Promise.all
дваawait
вызова могут быть начаты до разрешения любого из них.Обновить:
Первоначальный ответ затрудняет (а в некоторых случаях невозможен) правильную обработку отклонений обещаний. Правильное решение заключается в использовании
Promise.all
:Оригинальный ответ:
Просто убедитесь, что вы вызываете обе функции, прежде чем вы ждете одну из них:
источник
await
затем преобразуют их в реальные значения.Есть еще один способ без Promise.all () сделать это параллельно:
Во-первых, у нас есть 2 функции для печати чисел:
Это последовательно:
Это параллельно:
источник
Это может быть выполнено с Promise.allSettled () , который похож на,
Promise.all()
но без поведения быстрого отказа.Примечание . Это новейшая функция с ограниченной поддержкой браузера, поэтому я настоятельно рекомендую включить для этой функции полизаполнение.
источник
Я создал суть, тестирующую несколько разных способов выполнения обещаний, с результатами. Может быть полезно увидеть варианты, которые работают.
источник
Хотя установка p1, p2 и p3 не выполняет их строго параллельно, они не задерживают выполнение, и вы можете перехватывать контекстные ошибки с помощью перехвата.
источник
В моем случае у меня есть несколько задач, которые я хочу выполнять параллельно, но мне нужно сделать что-то другое с результатом этих задач.
И вывод:
источник
ожидайте Promise.all ([someCall (), anotherCall ()]); как уже упоминалось, будет действовать как забор потока (очень распространенный в параллельном коде, как CUDA), следовательно, он позволит выполнять все обещания в нем, не блокируя друг друга, но будет препятствовать продолжению выполнения до разрешения ALL.
Другим подходом, которым стоит поделиться, является асинхронность Node.js, которая также позволит вам легко контролировать уровень параллелизма, который обычно желателен, если задача напрямую связана с использованием ограниченных ресурсов в качестве вызова API, операций ввода-вывода, и т.п.
Кредиты автору статьи Medium ( подробнее )
источник
Я голосую за:
Помните, что в тот момент, когда вы вызываете функции, это может привести к неожиданному результату:
Но следующий всегда вызывает запрос на создание нового пользователя
источник
else
блок.Я создаю вспомогательную функцию waitAll, может быть, она может сделать ее слаще. Пока он работает только в nodejs , а не в браузере Chrome.
источник
for
Цикл последовательно ждет каждое обещание и добавляет результат в массив.