Вы не очень подробно описали свой код, поэтому я придумываю сценарий. Допустим, у вас есть 10 вызовов ajax, и вы хотите накопить результаты этих 10 вызовов ajax, а затем, когда все они будут выполнены, вы хотите что-то сделать. Вы можете сделать это так, накапливая данные в массиве и отслеживая, когда закончился последний:
Ручной счетчик
var ajaxCallsRemaining = 10;
var returnedData = [];
for (var i = 0; i < 10; i++) {
doAjax(whatever, function(response) {
// success handler from the ajax call
// save response
returnedData.push(response);
// see if we're done with the last ajax call
--ajaxCallsRemaining;
if (ajaxCallsRemaining <= 0) {
// all data is here now
// look through the returnedData and do whatever processing
// you want on it right here
}
});
}
Примечание: здесь важна обработка ошибок (не показана, потому что она зависит от того, как вы выполняете свои вызовы ajax). Вы захотите подумать о том, как вы собираетесь обрабатывать случай, когда один вызов ajax никогда не завершается, либо с ошибкой, либо застревает на долгое время, либо истекает по истечении длительного времени.
jQuery обещает
Добавляем к моему ответу в 2014 году. В наши дни обещания часто используются для решения этого типа проблемы, поскольку jQuery $.ajax()
уже возвращает обещание и $.when()
сообщит вам, когда все группы обещаний будут решены, и соберет для вас результаты возврата:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
// returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
// you can process it here
}, function() {
// error occurred
});
Стандартные обещания ES6
Как указано в ответе kba : если у вас есть среда со встроенными встроенными обещаниями (современный браузер или node.js, или с использованием babeljs transpile или с использованием полифилла обещаний), вы можете использовать обещания, указанные в ES6. См. Эту таблицу для поддержки браузера. Обещания поддерживаются практически во всех текущих браузерах, кроме IE.
Если doAjax()
возвращает обещание, вы можете сделать это:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
Если вам нужно превратить асинхронную операцию без обещания в операцию, которая возвращает обещание, вы можете «обещать» ее следующим образом:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
И затем используйте шаблон выше:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
Обещания Bluebird
Если вы используете библиотеку с более широким набором функций, такую как библиотека обещаний Bluebird , то в нее встроены некоторые дополнительные функции, упрощающие задачу:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});