Non sei stato molto specifico con il codice, quindi farò uno scenario. Diciamo che hai 10 chiamate ajax e vuoi accumulare i risultati da quelle 10 chiamate ajax e poi, quando hanno completato tutto, vuoi fare qualcosa. Si può fare in questo modo accumulando i dati in un array e tenere traccia di quando l'ultimo ha terminato:
contatore manuale del
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é è specifico di come stai effettuando le chiamate ajax). Dovrai pensare a come gestirai il caso quando una chiamata ajax non si concluderà mai, con un errore o rimarrà bloccata per un lungo periodo o dopo un lungo periodo di tempo.
jQuery Promises
Aggiungendo alla mia risposta nel 2014. In questi giorni, le promesse sono spesso utilizzati per risolvere questo tipo di problema in quanto jQuery di $.ajax()
restituisce già una promessa e $.when()
ti consente di sapere quando una gruppo di promesse sono tutti risolti e raccoglierà i risultati di ritorno per voi:
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 promette
As specified in kba's answer: se si dispone di un ambiente con promesse nativi incorporati (browser moderno o node.js o utilizzando babeljs transpile o utilizzando un polyfill promessa), quindi è possibile utilizzare promesse ES6-specificati. Vedi this table per il supporto del browser. Le promesse sono supportate in quasi tutti i browser correnti, tranne IE.
Se doAjax()
restituisce una promessa, allora si può fare questo:
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 avete bisogno di fare un'operazione non promessa asincrona in uno che restituisce una promessa, è possibile "promisify" si in questo modo:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
E, quindi utilizzare il modello di cui 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
});
Bluebird Promises
Se si utilizza un più ricco di funzionalità biblioteca come la Bluebird promise library, quindi ha alcune funzioni aggiuntive costruiti in per rendere questo più facile:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});
In async, vuoi dire aspettare una richiesta Ajax da completare? –
Nota, 'while (non tutto è fatto) {}' non funziona. Mentre sei impegnato ad aspettare, nessuno dei tuoi callback può essere eseguito. – cHao
Sì. Sto aspettando una chiamata asincrona a un'API esterna da restituire in modo che attivi i metodi di callback.Sì cHao, l'ho capito, ed è per questo che sto chiedendo aiuto qui: D – codersarepeople