Bạn chưa nói rõ lắm về mã của mình, vì vậy tôi sẽ tạo một kịch bản. Giả sử bạn có 10 lệnh gọi ajax và bạn muốn tích lũy kết quả từ 10 lệnh gọi ajax đó và sau đó khi tất cả chúng đã hoàn thành, bạn muốn làm điều gì đó. Bạn có thể làm như vậy bằng cách tích lũy dữ liệu trong một mảng và theo dõi thời điểm kết thúc cuối cùng:
Bộ đếm thủ công
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
}
});
}
Lưu ý: việc xử lý lỗi rất quan trọng ở đây (không được hiển thị vì nó dành riêng cho cách bạn thực hiện cuộc gọi ajax của mình). Bạn sẽ muốn nghĩ về cách bạn sẽ xử lý trường hợp khi một cuộc gọi ajax không bao giờ hoàn thành, có lỗi hoặc bị kẹt trong một thời gian dài hoặc hết thời gian sau một thời gian dài.
jQuery Hứa hẹn
Thêm vào câu trả lời của tôi vào năm 2014. Ngày nay, các lời hứa thường được sử dụng để giải quyết loại vấn đề này vì jQuery's $.ajax()
đã trả về một lời hứa và $.when()
sẽ cho bạn biết khi một nhóm lời hứa được giải quyết xong và sẽ thu thập kết quả trả về cho bạn:
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
});
Lời hứa tiêu chuẩn ES6
Như đã chỉ rõ trong câu trả lời của kba : nếu bạn có một môi trường với các hứa hẹn gốc được tích hợp sẵn (trình duyệt hiện đại hoặc node.js hoặc sử dụng babeljs transpile hoặc sử dụng đa điền vào lời hứa), thì bạn có thể sử dụng các hứa hẹn do ES6 chỉ định. Xem bảng này để được hỗ trợ trình duyệt. Hứa hẹn được hỗ trợ trong hầu hết các trình duyệt hiện tại, ngoại trừ IE.
Nếu doAjax()
trả về một lời hứa, thì bạn có thể thực hiện điều này:
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
});
Nếu bạn cần thực hiện một hoạt động không đồng bộ hóa không có lời hứa thành một hoạt động trả về một lời hứa, bạn có thể "quảng bá" nó như sau:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
Và, sau đó sử dụng mẫu trên:
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
});
Lời hứa của Bluebird
Nếu bạn sử dụng một thư viện giàu tính năng hơn, chẳng hạn như thư viện Bluebird hứa hẹn , thì nó có một số chức năng bổ sung được tích hợp sẵn để làm cho việc này dễ dàng hơn:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});