No has sido muy específico con tu código, así que inventaré un escenario. Digamos que tiene 10 llamadas ajax y desea acumular los resultados de esas 10 llamadas ajax y luego, cuando todas se hayan completado, desea hacer algo. Puede hacerlo así acumulando los datos en una matriz y haciendo un seguimiento de cuándo ha terminado el último:
Contador manual
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: el manejo de errores es importante aquí (no se muestra porque es específico de cómo está haciendo sus llamadas ajax). Querrá pensar en cómo manejará el caso cuando una llamada ajax nunca se complete, ya sea con un error o se atasque durante mucho tiempo o se agote después de mucho tiempo.
Promesas de jQuery
Agregando a mi respuesta en 2014. En estos días, las promesas se usan a menudo para resolver este tipo de problema, ya que jQuery $.ajax()
ya devuelve una promesa y $.when()
le informará cuando un grupo de promesas se resuelvan y recopilará los resultados devueltos por usted:
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
});
Promesas estándar de ES6
Como se especifica en la respuesta de kba : si tiene un entorno con promesas nativas integradas (navegador moderno o node.js o usando babeljs transpile o usando un polyfill de promesa), entonces puede usar promesas especificadas por ES6. Consulte esta tabla para conocer la compatibilidad con el navegador. Las promesas son compatibles con casi todos los navegadores actuales, excepto IE.
Si doAjax()
devuelve una promesa, puede hacer esto:
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
});
Si necesita convertir una operación asíncrona sin promesa en una que devuelva una promesa, puede "promisificarla" de esta manera:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
Y luego usa el patrón anterior:
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
});
Promesas de Bluebird
Si usa una biblioteca con más funciones, como la biblioteca de promesas Bluebird , entonces tiene algunas funciones adicionales integradas para facilitar esto:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});