Vì javascript trong một trình duyệt là một luồng (ngoại trừ những người làm web không tham gia ở đây) và một luồng thực thi javascript sẽ hoàn thành trước khi một luồng khác có thể chạy, câu lệnh của bạn:
while(flag==false) {}
chỉ đơn giản là sẽ chạy mãi mãi (hoặc cho đến khi trình duyệt phàn nàn về vòng lặp javascript không đáp ứng), trang sẽ xuất hiện ở trạng thái treo và không javascript nào khác có cơ hội chạy, do đó giá trị của cờ không bao giờ có thể thay đổi.
Để giải thích thêm một chút, Javascript là một ngôn ngữ hướng sự kiện . Điều đó có nghĩa là nó chạy một đoạn Javascript cho đến khi nó trả lại quyền điều khiển cho trình thông dịch. Sau đó, chỉ khi nó quay trở lại trình thông dịch, Javascript mới lấy sự kiện tiếp theo từ hàng đợi sự kiện và chạy nó.
Tất cả những thứ như bộ hẹn giờ và sự kiện mạng đều chạy qua hàng đợi sự kiện. Vì vậy, khi bộ hẹn giờ kích hoạt hoặc một yêu cầu mạng đến, nó không bao giờ "làm gián đoạn" Javascript hiện đang chạy. Thay vào đó, một sự kiện được đưa vào hàng đợi sự kiện Javascript và sau đó, khi Javascript hiện đang chạy kết thúc, sự kiện tiếp theo sẽ được kéo từ hàng đợi sự kiện và đến lượt nó chạy.
Vì vậy, khi bạn thực hiện một vòng lặp vô hạn chẳng hạn như while(flag==false) {}
, Javascript hiện đang chạy sẽ không bao giờ kết thúc và do đó sự kiện tiếp theo không bao giờ được kéo ra khỏi hàng đợi sự kiện và do đó giá trị của flag
không bao giờ bị thay đổi. Điều quan trọng ở đây là Javascript không được điều khiển gián đoạn . Khi bộ đếm thời gian kích hoạt, nó không làm gián đoạn Javascript hiện đang chạy, hãy chạy một số Javascript khác và sau đó để Javascript hiện đang chạy tiếp tục. Nó chỉ được đưa vào hàng đợi sự kiện chờ cho đến khi Javascript hiện đang chạy hoàn tất để đến lượt nó chạy.
Những gì bạn cần làm là suy nghĩ lại cách mã của bạn hoạt động và tìm một cách khác để kích hoạt bất kỳ mã nào bạn muốn chạy khi flag
giá trị thay đổi. Javascript được thiết kế như một ngôn ngữ hướng sự kiện. Vì vậy, những gì bạn cần làm là tìm ra những sự kiện mà bạn có thể đăng ký quan tâm để bạn có thể lắng nghe sự kiện có thể khiến cờ thay đổi và bạn có thể kiểm tra cờ trên sự kiện đó hoặc bạn có thể kích hoạt sự kiện của riêng mình từ bất kỳ mã nào có thể thay đổi cờ hoặc bạn có thể triển khai một hàm gọi lại mà bất kỳ mã nào thay đổi mà cờ đó có thể gọi lệnh gọi lại của bạn bất cứ khi nào đoạn mã chịu trách nhiệm thay đổi giá trị cờ sẽ thay đổi giá trị của true
nó, nó chỉ gọi hàm gọi lại và do đó mã của bạn muốn chạy khi cờ được đặt thànhtrue
sẽ chạy vào đúng thời điểm. Điều này hiệu quả hơn nhiều so với việc cố gắng sử dụng một số loại bộ đếm thời gian để liên tục kiểm tra giá trị cờ.
function codeThatMightChangeFlag(callback) {
if (condition happens to change flag value) {
callback();
}
}
jQuery.Deferred
,Q
,async
, ...