Làm cách nào để tạo một hàm chờ cho đến khi tất cả các yêu cầu jQuery Ajax được thực hiện bên trong một hàm khác?
Nói tóm lại, tôi cần đợi tất cả các yêu cầu Ajax được thực hiện trước khi tôi thực hiện tiếp theo. Nhưng bằng cách nào?
Làm cách nào để tạo một hàm chờ cho đến khi tất cả các yêu cầu jQuery Ajax được thực hiện bên trong một hàm khác?
Nói tóm lại, tôi cần đợi tất cả các yêu cầu Ajax được thực hiện trước khi tôi thực hiện tiếp theo. Nhưng bằng cách nào?
Câu trả lời:
Bây giờ jQuery định nghĩa một hàm khi cho mục đích này.
Nó chấp nhận bất kỳ số lượng đối tượng Trì hoãn nào làm đối số và thực thi một hàm khi tất cả chúng giải quyết.
Điều đó có nghĩa là, nếu bạn muốn bắt đầu (ví dụ) bốn yêu cầu ajax, sau đó thực hiện một hành động khi chúng được thực hiện, bạn có thể làm một cái gì đó như thế này:
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four ajax requests resolve.
// a1, a2, a3 and a4 are lists of length 3 containing the response text,
// status, and jqXHR object for each of the four ajax calls respectively.
});
function ajax1() {
// NOTE: This function must return the value
// from calling the $.ajax() method.
return $.ajax({
url: "someUrl",
dataType: "json",
data: yourJsonData,
...
});
}
Theo tôi, nó tạo ra một cú pháp rõ ràng và rõ ràng và tránh liên quan đến bất kỳ biến toàn cục nào như ajaxStart và ajaxStop, có thể có tác dụng phụ không mong muốn khi trang của bạn phát triển.
Nếu bạn không biết trước có bao nhiêu đối số ajax bạn cần chờ (nghĩa là bạn muốn sử dụng một số lượng đối số khác nhau), thì vẫn có thể thực hiện được nhưng chỉ cần một chút khó khăn hơn. Xem Pass trong một mảng của Trì hoãn đến $ .when () (và có thể jQuery .when xử lý sự cố với số lượng đối số thay đổi ).
Nếu bạn cần kiểm soát sâu hơn các chế độ thất bại của các tập lệnh ajax, v.v., bạn có thể lưu đối tượng được trả về bởi .when()
- đó là một đối tượng Promise jQuery bao gồm tất cả các truy vấn ajax ban đầu. Bạn có thể gọi .then()
hoặc .fail()
trên đó để thêm các trình xử lý thành công / thất bại chi tiết.
$.when
trả về một Promise
đối tượng có các phương thức hữu ích hơn, không chỉ .done
. Ví dụ: với .then(onSuccess, onFailure)
phương pháp bạn có thể phản ứng khi cả hai yêu cầu thành công hoặc ít nhất một trong số chúng không thành công.
fail
trường hợp. Không giống như done
, fail
bắn ngay lập tức vào lần thất bại đầu tiên và coi thường những người trì hoãn còn lại.
onFailure
chức năng có thể được đính kèm. Như tôi đã chỉ ra trong một bình luận cho câu hỏi của OP: anh ta có thể muốn chỉ ra chính xác hơn những gì anh ta có nghĩa là "thực hiện". "Ryan Mohr" cũng đã có một điểm rất tốt về thực tế là fail
xử lý khác nhau như done
, một số đọc thêm việc phải làm về Promises
tôi đoán html5rocks.com/en/tutorials/es6/promises
Nếu bạn muốn biết khi nào tất cả các ajax
yêu cầu kết thúc trong tài liệu của bạn, bất kể có bao nhiêu trong số chúng tồn tại, chỉ cần sử dụng sự kiện $ .ajaxStop theo cách này:
$(document).ajaxStop(function () {
// 0 === $.active
});
Trong trường hợp này, bạn không cần phải đoán có bao nhiêu yêu cầu đang xảy ra trong ứng dụng, có thể kết thúc trong tương lai, cũng không đào sâu vào các hàm logic phức tạp hoặc tìm chức năng nào đang thực hiện
HTTP(S)
yêu cầu.
$.ajaxStop
ở đây cũng có thể được liên kết với bất kỳHTML
nút nào mà bạn nghĩ có thể được sửa đổi bởi requst.
Cập nhật:
Nếu bạn muốn ES
sử dụng cú pháp, thì bạn có thể sử dụng Promise.all cho ajax
các phương thức đã biết :
Promise.all([ajax1(), ajax2()]).then(() => {
// all requests finished successfully
}).catch(() => {
// all requests finished but one or more failed
})
Một điểm thú vị ở đây là nó hoạt động cả với Promises
và$.ajax
yêu cầu.
Dưới đây là trình diễn jsFiddle .
Cập nhật 2:
Phiên bản mới hơn sử dụng cú pháp async / await :
try {
const results = await Promise.all([ajax1(), ajax2()])
// do other actions
} catch(ex) { }
Tôi đã tìm thấy một câu trả lời tốt bằng cách gnarf bản thân mình, đó chính xác là những gì tôi đang tìm kiếm :)
jQuery ajaxQueue
//This handles the queues
(function($) {
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
var oldComplete = ajaxOpts.complete;
ajaxQueue.queue(function(next) {
ajaxOpts.complete = function() {
if (oldComplete) oldComplete.apply(this, arguments);
next();
};
$.ajax(ajaxOpts);
});
};
})(jQuery);
Sau đó, bạn có thể thêm yêu cầu ajax vào hàng đợi như thế này:
$.ajaxQueue({
url: 'page.php',
data: {id: 1},
type: 'POST',
success: function(data) {
$('#status').html(data);
}
});
Sử dụng ajaxStop
sự kiện.
Ví dụ: giả sử bạn có tải ... tin nhắn trong khi tìm nạp 100 yêu cầu ajax và bạn muốn ẩn tin nhắn đó sau khi tải.
Từ tài liệu jQuery :
$("#loading").ajaxStop(function() {
$(this).hide();
});
Xin lưu ý rằng nó sẽ đợi tất cả các yêu cầu ajax được thực hiện trên trang đó.
LƯU Ý: Các câu trả lời trên sử dụng chức năng không tồn tại tại thời điểm câu trả lời này được viết. Tôi khuyên bạn nên sử dụngjQuery.when()
thay vì các phương pháp này, nhưng tôi để lại câu trả lời cho các mục đích lịch sử.
-
Bạn có thể có được bằng một semaphore đếm đơn giản, mặc dù cách bạn triển khai nó sẽ phụ thuộc vào mã của bạn. Một ví dụ đơn giản sẽ giống như ...
var semaphore = 0, // counting semaphore for ajax requests
all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts
semaphore++;
$.get('ajax/test1.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test2.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test3.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test4.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;
Nếu bạn muốn điều này hoạt động như {async: false} nhưng bạn không muốn khóa trình duyệt, bạn có thể thực hiện điều tương tự với hàng đợi jQuery.
var $queue = $("<div/>");
$queue.queue(function(){
$.get('ajax/test1.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test2.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test3.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test4.html', function(data) {
$queue.dequeue();
});
});
.get()
. Bằng cách đó, ít nhất bạn không sao chép mã đó. Không chỉ vậy mà khai báo function(){}
mỗi lần phân bổ bộ nhớ mỗi lần! Thực tế khá tệ nếu bạn có thể gọi một hàm được xác định tĩnh.
javascript dựa trên sự kiện, vì vậy bạn không bao giờ nên chờ đợi , thay vào đó hãy đặt hook / callbacks
Bạn có thể chỉ cần sử dụng các phương pháp thành công / hoàn chỉnh của jquery.ajax
Hoặc bạn có thể sử dụng .ajaxComplete :
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler.');
//and you can do whatever other processing here, including calling another function...
}
});
mặc dù youy nên đăng một mã giả về cách (các) yêu cầu ajax của bạn được gọi là chính xác hơn ...
Một cách giải quyết nhỏ là như thế này:
// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
counter++;
if( counter >= ajaxCalls ) {
// When all ajax calls has been done
// Do something like hide waiting images, or any else function call
$('*').css('cursor', 'auto');
}
};
var loadPersons = function() {
// Show waiting image, or something else
$('*').css('cursor', 'wait');
var url = global.ctx + '/loadPersons';
$.getJSON(url, function(data) {
// Fun things
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCountries = function() {
// Do things
var url = global.ctx + '/loadCountries';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCities = function() {
// Do things
var url = global.ctx + '/loadCities';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
$(document).ready(function(){
loadPersons();
loadCountries();
loadCities();
});
Hy vọng có thể hữu ích ...
jQuery cho phép bạn chỉ định nếu bạn muốn yêu cầu ajax không đồng bộ hay không. Bạn có thể chỉ cần làm cho các yêu cầu ajax được đồng bộ hóa và sau đó phần còn lại của mã sẽ không thực thi cho đến khi chúng trở lại.
Ví dụ:
jQuery.ajax({
async: false,
//code
});
Nếu bạn cần một cái gì đó đơn giản; một lần và thực hiện gọi lại
//multiple ajax calls above
var callback = function () {
if ($.active !== 0) {
setTimeout(callback, '500');
return;
}
//whatever you need to do here
//...
};
callback();
Ngoài ra, bạn có thể sử dụng async.js .
Tôi nghĩ rằng nó tốt hơn $ .when bởi vì bạn có thể hợp nhất tất cả các loại cuộc gọi không đồng bộ không hỗ trợ lời hứa ngoài hộp như thời gian chờ, cuộc gọi SqlLite, v.v. và không chỉ yêu cầu ajax.
Trên cơ sở câu trả lời @BBonifield, tôi đã viết một hàm tiện ích để logic semaphore không được lan truyền trong tất cả các lệnh gọi ajax.
untilAjax
là hàm tiện ích gọi hàm gọi lại khi tất cả các ajaxCalls được hoàn thành.
ajaxObjs
là một mảng các đối tượng thiết lập ajax [http://api.jquery.com/jQuery.ajax/]
.
fn
là chức năng gọi lại
function untilAjax(ajaxObjs, fn) {
if (!ajaxObjs || !fn) {
return;
}
var ajaxCount = ajaxObjs.length,
succ = null;
for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
succ = ajaxObjs[i]['success'];
ajaxObjs[i]['success'] = function(data) { //modified success handler
if (succ) {
succ(data);
}
ajaxCount--;
if (ajaxCount == 0) {
fn(); //modify statement suitably if you want 'this' keyword to refer to another object
}
};
$.ajax(ajaxObjs[i]); //make ajax call
succ = null;
};
Ví dụ: doSomething
hàm sử dụng untilAjax
.
function doSomething() {
// variable declarations
untilAjax([{
url: 'url2',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url1',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url2',
dataType: 'json',
success: function(response) {
//do something with success data
}
}], function() {
// logic after all the calls are completed.
});
}
Tôi thực sự khuyên bạn nên sử dụng $ .when () nếu bạn bắt đầu từ đầu.
Mặc dù câu hỏi này có hơn triệu câu trả lời, tôi vẫn không tìm thấy điều gì hữu ích cho trường hợp của mình. Giả sử bạn phải đối phó với một cơ sở mã hiện có, đã thực hiện một số cuộc gọi ajax và không muốn giới thiệu sự phức tạp của các lời hứa và / hoặc làm lại toàn bộ.
Chúng ta có thể dễ dàng tận dụng jQuery .data
, .on
và .trigger
chức năng mà đã là một phần của jQuery kể từ mãi mãi.
Những thứ tốt về giải pháp của tôi là:
rõ ràng những gì gọi lại chính xác phụ thuộc vào
chức năng triggerNowOrOnLoaded
không quan tâm nếu dữ liệu đã được tải hoặc chúng tôi vẫn đang chờ nó
Thật dễ dàng để cắm nó vào một mã hiện có
$(function() {
// wait for posts to be loaded
triggerNowOrOnLoaded("posts", function() {
var $body = $("body");
var posts = $body.data("posts");
$body.append("<div>Posts: " + posts.length + "</div>");
});
// some ajax requests
$.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
$("body").data("posts", data).trigger("posts");
});
// doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests
$.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
$("body").data("users", data).trigger("users");
});
// wait for both types
triggerNowOrOnLoaded(["posts", "users"], function() {
var $body = $("body");
var posts = $body.data("posts");
var users = $body.data("users");
$body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
});
// works even if everything has already loaded!
setTimeout(function() {
// triggers immediately since users have been already loaded
triggerNowOrOnLoaded("users", function() {
var $body = $("body");
var users = $body.data("users");
$body.append("<div>Delayed Users: " + users.length + "</div>");
});
}, 2000); // 2 seconds
});
// helper function
function triggerNowOrOnLoaded(types, callback) {
types = $.isArray(types) ? types : [types];
var $body = $("body");
var waitForTypes = [];
$.each(types, function(i, type) {
if (typeof $body.data(type) === 'undefined') {
waitForTypes.push(type);
}
});
var isDataReady = waitForTypes.length === 0;
if (isDataReady) {
callback();
return;
}
// wait for the last type and run this function again for the rest of the types
var waitFor = waitForTypes.pop();
$body.on(waitFor, function() {
// remove event handler - we only want the stuff triggered once
$body.off(waitFor);
triggerNowOrOnLoaded(waitForTypes, callback);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>Hi!</body>
Tôi đang sử dụng kiểm tra kích thước khi tất cả tải ajax hoàn tất
function get_ajax(link, data, callback) {
$.ajax({
url: link,
type: "GET",
data: data,
dataType: "json",
success: function (data, status, jqXHR) {
callback(jqXHR.status, data)
},
error: function (jqXHR, status, err) {
callback(jqXHR.status, jqXHR);
},
complete: function (jqXHR, status) {
}
})
}
function run_list_ajax(callback){
var size=0;
var max= 10;
for (let index = 0; index < max; index++) {
var link = 'http://api.jquery.com/ajaxStop/';
var data={i:index}
get_ajax(link,data,function(status, data){
console.log(index)
if(size>max-2){
callback('done')
}
size++
})
}
}
run_list_ajax(function(info){
console.log(info)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
Để mở rộng câu trả lời của Alex, tôi có một ví dụ với các đối số và lời hứa khác nhau. Tôi muốn tải hình ảnh qua ajax và hiển thị chúng trên trang sau khi tất cả chúng được tải.
Để làm điều đó, tôi đã sử dụng như sau:
let urlCreator = window.URL || window.webkitURL;
// Helper function for making ajax requests
let fetch = function(url) {
return $.ajax({
type: "get",
xhrFields: {
responseType: "blob"
},
url: url,
});
};
// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));
// Use the spread operator to wait for all requests
$.when(...files).then(function() {
// If we have multiple urls, then loop through
if(urls.length > 1) {
// Create image urls and tags for each result
Array.from(arguments).forEach(data => {
let imageUrl = urlCreator.createObjectURL(data[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
});
}
else {
// Create image source and tag for result
let imageUrl = urlCreator.createObjectURL(arguments[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
}
});
Đã cập nhật để hoạt động cho một hoặc nhiều url: https://jsfiddle.net/euypj5w9/
Như các câu trả lời khác đã đề cập, bạn có thể sử dụng ajaxStop()
để đợi cho đến khi tất cả yêu cầu ajax được hoàn thành.
$(document).ajaxStop(function() {
// This function will be triggered every time any ajax request is requested and completed
});
Nếu bạn muốn thực hiện nó cho một ajax()
yêu cầu cụ thể, cách tốt nhất bạn có thể làm là sử dụng complete()
phương thức bên trong yêu cầu ajax nhất định:
$.ajax({
type: "POST",
url: "someUrl",
success: function(data) {
// This function will be triggered when ajax returns a 200 status code (success)
},
complete: function() {
// This function will be triggered always, when ajax request is completed, even it fails/returns other status code
},
error: function() {
// This will be triggered when ajax request fail.
}
});
Nhưng, nếu bạn chỉ cần đợi một vài và yêu cầu ajax nhất định sẽ được thực hiện? Sử dụng các javascript tuyệt vời hứa hẹn sẽ đợi cho đến khi các ajax bạn muốn chờ đợi được thực hiện. Tôi đã làm một ví dụ ngắn gọn, dễ đọc và dễ đọc để cho bạn thấy các lời hứa hoạt động như thế nào với ajax.
Hãy xem ví dụ tiếp theo . Tôi đã sử dụng setTimeout
để làm rõ ví dụ.
// Note:
// resolve() is used to mark the promise as resolved
// reject() is used to mark the promise as rejected
$(document).ready(function() {
$("button").on("click", function() {
var ajax1 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
xhrFields: { responseType: 'blob'},
success: function(data) {
setTimeout(function() {
$('#image1').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax1 resolved");
}, 1000);
},
error: function() {
reject(" Promise ajax1 rejected");
},
});
});
var ajax2 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://cdn1.iconfinder.com/data/icons/social-media-vol-1-1/24/_github-512.png",
xhrFields: { responseType: 'blob' },
success: function(data) {
setTimeout(function() {
$('#image2').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax2 resolved");
}, 1500);
},
error: function() {
reject(" Promise ajax2 rejected");
},
});
});
var ajax3 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://miro.medium.com/max/632/1*LUfpOf7teWvPdIPTBmYciA.png",
xhrFields: { responseType: 'blob' },
success: function(data) {
setTimeout(function() {
$('#image3').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax3 resolved");
}, 2000);
},
error: function() {
reject(" Promise ajax3 rejected");
},
});
});
Promise.all([ajax1, ajax2, ajax3]).then(values => {
console.log("We waited until ajax ended: " + values);
console.log("My few ajax ended, lets do some things!!")
}, reason => {
console.log("Promises failed: " + reason);
});
// Or if you want wait for them individually do it like this
// ajax1.then(values => {
// console.log("Promise 1 resolved: " + values)
// }, reason => {
// console.log("Promise 1 failed: " + reason)
// });
});
});
img {
max-width: 200px;
max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Make AJAX request</button>
<div id="newContent">
<img id="image1" src="">
<img id="image2" src="">
<img id="image3" src="">
</div>
Tôi tìm thấy cách đơn giản, nó sử dụng shift()
function waitReq(id)
{
jQuery.ajax(
{
type: 'POST',
url: ajaxurl,
data:
{
"page": id
},
success: function(resp)
{
...........
// check array length if not "0" continue to use next array value
if(ids.length)
{
waitReq(ids.shift()); // 2
)
},
error: function(resp)
{
....................
if(ids.length)
{
waitReq(ids.shift());
)
}
});
}
var ids = [1, 2, 3, 4, 5];
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1
Giải pháp của tôi là như sau
var request;
...
'services': {
'GetAddressBookData': function() {
//This is the primary service that loads all addressbook records
request = $.ajax({
type: "POST",
url: "Default.aspx/GetAddressBook",
contentType: "application/json;",
dataType: "json"
});
},
...
'apps': {
'AddressBook': {
'data': "",
'Start': function() {
...services.GetAddressBookData();
request.done(function(response) {
trace("ajax successful");
..apps.AddressBook.data = response['d'];
...apps.AddressBook.Filter();
});
request.fail(function(xhr, textStatus, errorThrown) {
trace("ajax failed - " + errorThrown);
});
Làm việc khá độc đáo. Tôi đã thử rất nhiều cách khác nhau để làm điều này, nhưng tôi thấy đây là cách đơn giản nhất và có thể tái sử dụng nhiều nhất. Hy vọng nó giúp
Nhìn vào giải pháp của tôi:
1. Đưa chức năng này (và biến) vào tệp javascript của bạn:
var runFunctionQueue_callback;
function runFunctionQueue(f, index, callback) {
var next_index = index + 1
if (callback !== undefined) runFunctionQueue_callback = callback;
if (f[next_index] !== undefined) {
console.log(index + ' Next function avalaible -> ' + next_index);
$.ajax({
type: 'GET',
url: f[index].file,
data: (f[index].data),
complete: function() {
runFunctionQueue(f, next_index);
}
});
} else {
console.log(index + ' Last function');
$.ajax({
type: 'GET',
url: f[index].file,
data: (f[index].data),
async: false,
complete: runFunctionQueue_callback
});
}
}
2.Làm một mảng với các yêu cầu của bạn, như thế này:
var f = [
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}}
];
3. Tạo chức năng gọi lại:
function Function_callback() {
alert('done');
}
4.Call chức năng runFunctionQueue với các tham số:
runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function
$.when
không làm việc cho tôi, callback(x)
thay vì return x
làm việc như được mô tả ở đây: https://stackoverflow.com/a/13455253/10357604
Hãy thử cách này. tạo một vòng lặp bên trong chức năng tập lệnh java để đợi cho đến khi cuộc gọi ajax kết thúc.
function getLabelById(id)
{
var label = '';
var done = false;
$.ajax({
cache: false,
url: "YourMvcActionUrl",
type: "GET",
dataType: "json",
async: false,
error: function (result) {
label='undefined';
done = true;
},
success: function (result) {
label = result.Message;
done = true;
}
});
//A loop to check done if ajax call is done.
while (!done)
{
setTimeout(function(){ },500); // take a sleep.
}
return label;
}
setTimeout()
KHÔNG take a sleep
. Trong trường hợp này, bạn chỉ cần chặn tất cả các tab cho đến khi done
trở thành sự thật.
done
sẽ không bao giờ đúng trong khi vòng lặp while vẫn đang chạy. Nếu vòng lặp while đang chạy, vòng lặp sự kiện không thể tiếp tục và do đó sẽ không bao giờ chạy lại cuộc gọi thành công ajax.