您对代码的了解不是很明确,所以我将提出一个方案。假设您有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年为我添加了答案。这些天来,promise通常用于解决此类问题,因为jQuery $.ajax()
已经返回了promise,并且$.when()
将在一组promise全部解决时通知您,并会为您收集返回结果:
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的回答所指定:如果您拥有一个内置本机promise的环境(现代浏览器或node.js或使用babeljs transpile或诺言polyfill),则可以使用ES6指定的诺言。请参阅此表以获取浏览器支持。除了IE,几乎所有当前的浏览器都支持Promise。
如果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 promise库),那么它将内置一些附加功能以使其更容易:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});