Bạn chưa thật cụ thể với 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 cuộc gọi ajax và bạn muốn tích lũy kết quả từ 10 cuộc gọi ajax đó và sau đó khi họ hoàn tất, bạn muốn làm điều gì đó. Bạn có thể làm điều đó như thế này bằng cách tích lũy các dữ liệu trong một mảng và theo dõi khi người cuối cùng đã hoàn tất:
Counter 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
}
});
}
Lưu ý: xử lý lỗi là quan trọng ở đây (không được hiển thị vì cụ thể là cách bạn thực hiện cuộc gọi ajax). Bạn sẽ muốn suy nghĩ về cách bạn sẽ xử lý các trường hợp khi một cuộc gọi ajax không bao giờ hoàn thành, hoặc với một lỗi hoặc bị mắc kẹt trong một thời gian dài hoặc thời gian ra sau một thời gian dài.
jQuery Promises
Thêm vào câu trả lời của tôi trong năm 2014. Những ngày này, những lời hứa thường được sử dụng để giải quyết vấn đề kiểu này kể từ jQuery $.ajax()
đã trả về một lời hứa và $.when()
sẽ cho bạn biết khi một nhóm các lời hứa đều giải quyết và sẽ thu thập các kết quả trả lại 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
});
ES6 Chuẩn Promises
As specified in kba's answer: nếu bạn có một môi trường với những lời hứa mẹ đẻ built-in (trình duyệt hiện đại hay Node.js hoặc sử dụng babeljs transpile hoặc sử dụng một polyfill lời hứa), sau đó bạn có thể sử dụng những lời hứa ES6 chỉ định. Xem this table để được hỗ trợ trình duyệt. Lời hứa được hỗ trợ khá nhiều trong tất cả 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, sau đó bạn có thể làm đ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 phải thực hiện một hoạt động phi hứa async thành một trong đó trả về một lời hứa, bạn có thể "promisify" nó như thế này:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
Và, sau đó sử dụng các mô hình 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
});
Bluebird Promises
Nếu bạn sử dụng một tính năng hơn thư viện phong phú như Bluebird promise library, sau đó nó có một số chức năng bổ sung xây dựng trong để làm điều 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
});
Khi bạn đồng ý chờ yêu cầu Ajax hoàn tất? –
Lưu ý, 'trong khi (không phải tất cả được thực hiện) {}' sẽ không hoạt động. Trong khi bạn đang chờ đợi, không có cuộc gọi lại nào của bạn có thể chạy. – cHao
Có. Tôi đang chờ một cuộc gọi async đến một API bên ngoài để trở về để nó sẽ kích hoạt các phương thức gọi lại.Vâng, tôi nhận ra rằng, đó là lý do tại sao tôi yêu cầu giúp đỡ ở đây: D – codersarepeople