Non sei stato molto specifico con il tuo codice, quindi creerò uno scenario. Diciamo che hai 10 chiamate ajax e vuoi accumulare i risultati di quelle 10 chiamate ajax e poi quando hanno tutte completato vuoi fare qualcosa. Puoi farlo in questo modo accumulando i dati in un array e tenendo traccia di quando l'ultimo è finito:
Contatore manuale
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
}
});
}
Nota: la gestione degli errori è importante qui (non mostrata perché è specifica per come stai effettuando le chiamate ajax). Dovrai pensare a come gestirai il caso quando una chiamata ajax non viene mai completata, con un errore o si blocca per molto tempo o scade dopo molto tempo.
jQuery Promises
In aggiunta alla mia risposta nel 2014. In questi giorni, le promesse vengono spesso utilizzate per risolvere questo tipo di problema poiché jQuery $.ajax()
restituisce già una promessa e $.when()
ti farà sapere quando un gruppo di promesse sarà stato risolto e raccoglierà i risultati di ritorno per te:
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
});
Promesse standard ES6
Come specificato nella risposta di kba : se hai un ambiente con promesse native integrate (browser moderno o node.js o utilizzando babeljs transpile o utilizzando un polyfill di promesse), puoi utilizzare promesse specificate da ES6. Vedi questa tabella per il supporto del browser. Le promesse sono supportate praticamente in tutti i browser attuali, tranne IE.
Se doAjax()
restituisce una promessa, puoi farlo:
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
});
Se devi trasformare un'operazione asincrona senza promessa in un'operazione che restituisce una promessa, puoi "prometterla" in questo modo:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
E poi usa lo schema sopra:
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
});
Promesse di Bluebird
Se utilizzi una libreria più ricca di funzionalità come la libreria di promesse di Bluebird , ha alcune funzioni aggiuntive integrate per renderlo più semplice:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});