Ви не дуже точно визначилися зі своїм кодом, тому я складу сценарій. Скажімо, у вас є 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 , тоді в неї вбудовані додаткові функції, які полегшують це:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});