У меня есть код в javascript, который выглядит примерно так:
forloop {
//async call, returns an array to its callback
}
После выполнения ВСЕХ этих асинхронных вызовов я хочу вычислить минимум по всем массивам.
Как я могу дождаться их всех?
Моя единственная идея прямо сейчас - создать массив логических значений с именем done и установить для done [i] значение true в i-й функции обратного вызова, а затем сказать while (не все выполнено) {}
edit: Я полагаю, что одним из возможных, но уродливых решений было бы отредактировать массив done в каждом обратном вызове, а затем вызвать метод, если все остальные done установлены из каждого обратного вызова, поэтому последний обратный вызов для завершения вызовет продолжающийся метод.
Заранее спасибо.
javascript
asynchronous
кодеры
источник
источник
while (not all are done) { }
не сработает. Пока вы заняты ожиданием, ни один из ваших обратных вызовов не может выполняться.Ответы:
Вы не очень подробно описали свой код, поэтому я придумываю сценарий. Допустим, у вас есть 10 вызовов ajax, и вы хотите накопить результаты этих 10 вызовов ajax, а затем, когда все они будут выполнены, вы хотите что-то сделать. Вы можете сделать это так, накапливая данные в массиве и отслеживая, когда закончился последний:
Ручной счетчик
Примечание: здесь важна обработка ошибок (не показана, потому что она зависит от того, как вы выполняете свои вызовы ajax). Вы захотите подумать о том, как вы собираетесь обрабатывать случай, когда один вызов ajax никогда не завершается, либо с ошибкой, либо застревает на долгое время, либо истекает по истечении длительного времени.
jQuery обещает
Добавляем к моему ответу в 2014 году. В наши дни обещания часто используются для решения этого типа проблемы, поскольку jQuery
$.ajax()
уже возвращает обещание и$.when()
сообщит вам, когда все группы обещаний будут решены, и соберет для вас результаты возврата:Стандартные обещания ES6
Как указано в ответе kba : если у вас есть среда со встроенными встроенными обещаниями (современный браузер или node.js, или с использованием babeljs transpile или с использованием полифилла обещаний), вы можете использовать обещания, указанные в ES6. См. Эту таблицу для поддержки браузера. Обещания поддерживаются практически во всех текущих браузерах, кроме IE.
Если
doAjax()
возвращает обещание, вы можете сделать это:Если вам нужно превратить асинхронную операцию без обещания в операцию, которая возвращает обещание, вы можете «обещать» ее следующим образом:
И затем используйте шаблон выше:
Обещания Bluebird
Если вы используете библиотеку с более широким набором функций, такую как библиотека обещаний Bluebird , то в нее встроены некоторые дополнительные функции, упрощающие задачу:
источник
doAjax()
один из вариантов, который возвращает обещание. То же, что иfetch()
.Регистрация с 2015 года: теперь у нас есть встроенные обещания в самых последних версиях браузеров (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 и браузер Android 4.4.4 и iOS Safari 8.4, но не в Internet Explorer, Opera Mini и более ранних версиях). Android).
Если мы хотим выполнить 10 асинхронных действий и получить уведомление, когда все они будут завершены, мы можем использовать нативные
Promise.all
, без каких-либо внешних библиотек:источник
Promises.all()
должно бытьPromise.all()
.Promise.all()
в которых нет текущих версий IE.Вы можете использовать объект Deferred jQuery вместе с методом when .
источник
jQuery
что обычно означает, что OP не хотел ответа jQuery.Вы можете эмулировать это так:
то каждый асинхронный вызов делает следующее:
а в каждом асинхронном вызове в конце метода вы добавляете эту строку:
Другими словами, вы имитируете обратный отсчет с защелкой.
источник
На мой взгляд, это самый изящный способ.
Promise.all
FetchAPI
(у меня по какой-то причине Array.map не работает внутри функций .then. Но вы можете использовать .forEach и [] .concat () или что-то подобное)
источник
return responses.map(response => { return response.json(); })
, илиreturn responses.map(response => response.json())
.Используйте библиотеку потока управления, например
after
источник