Вы не очень-то определились с вашим кодом, поэтому я состану сценарий. Допустим, у вас 10 вызовов ajax, и вы хотите аккумулировать результаты этих 10 аякс-звонков, а затем, когда они все закончили, вы хотите что-то сделать. Вы можете сделать это так, накапливая данные в массиве и отслеживании, когда последний закончил:
Ручной счетчик
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 никогда не завершается, либо с ошибкой, либо застрял в течение долгого времени или времени после долгого времени.
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 Standard Обещание
As specified in kba's answer: если у вас есть среда с носителями обещаний встроенных (современным браузером или node.js или с помощью babeljs transpile или используя обещание polyfill), то вы можете использовать ES6-определенные обещания. См. this table для поддержки браузера. Обещания поддерживаются практически во всех текущих браузерах, кроме 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
});
Если вам нужно сделать операцию, не обещание асинхронной в тот, который возвращает обещание, вы можете «promisify» его как это:
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 promise library, то она имеет некоторые дополнительные функции, встроенные в, чтобы сделать это проще:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});
В случае асинхронного вызова вы ожидаете завершения запроса Ajax? –
Обратите внимание: 'while (не все сделано) {}' не будет работать. Пока вы заняты, ни один из ваших обратных вызовов не может работать. – cHao
Да. Я жду асинхронного вызова внешнего API, чтобы он возвращался, чтобы он вызывал методы обратного вызова.Да, caao, я понял это, поэтому я прошу о помощи здесь: D – codersarepeople