2015-11-27 14 views
18

Trong JavaScript, setTimeout(callback, delay) có nghĩa là "hãy gọi callback sau delay mili giây". Nhưng nếu delay0 thì sao? Nó có nên gọi callback ngay lập tức không?SetTimeout làm gì khi được đặt thành 0 mili giây?

Tôi đang bối rối vì những gì tôi thấy khi chạy đoạn mã sau:

setTimeout(function() { 
    console.log('AAA'); 
}, 0); // Call this in 0 milliseconds 

for (i = 0; i < 1000; i++) { 
    console.log('BBB'); 
} 
for (i = 0; i < 1000; i++) { 
    console.log('CCC'); 
} 
for (i = 0; i < 1000; i++) { 
    console.log('DDD'); 
} 
for (i = 0; i < 1000; i++) { 
    console.log('EEE'); 
} 

này ghi lại sau vào giao diện điều khiển:

console_log

tôi mong đợi để xem AAA đăng nhập nhiều sớm hơn thế. Đã có thời gian để thực hiện 4000 cuộc gọi khác đến console.log trước khi một chức năng cần được gọi ngay lập tức.

Ai đó có thể giải thích những gì setTimeout đang thực hiện khi trì hoãn được đặt thành 0 mili giây không?

+10

Kiểm tra [này] (http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful) – Trung

+0

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout – Nipuna

+1

Một grea t giải thích về câu hỏi của bạn! Kiểm tra [this] (http://geekabyte.blogspot.in/2014/01/javascript-effect-of-setting-settimeout.html). – deepakb

Trả lời

23

Một vài sự kiện hữu ích có thể giúp làm rõ những gì đang xảy ra:

  1. JavaScript là đơn luồng. Số gọi lại không đồng bộ được gán cho thông báo được đặt trong một hàng đợi tin nhắn .
  2. Khi không có mã nào hiện đang thực thi, vòng lặp sự kiện vòng lặp thăm dò hàng đợi thông báo, yêu cầu thông báo tiếp theo xếp hàng được xử lý (đã thực hiện).
  3. setTimeout thêm thông báo (với cuộc gọi lại được cung cấp) vào cuối hàng đợi này sau khi thời gian trễ được chỉ định đã trôi qua.

(Lưu ý: điều này có nghĩa sự chậm trễ trong một cuộc gọi setTimeout không phải là một điều chắc chắn, nó là chậm trễ tối thiểu trước khi gọi lại được thực hiện Thời gian thực hiện phụ thuộc vào phải mất bao lâu để xử lý bất kỳ tin nhắn. phía trước nó trong hàng đợi.)

Vậy điều gì xảy ra nếu độ trễ được đặt thành 0? Một thư mới sẽ được thêm vào hàng đợi ngay lập tức và sẽ được xử lý khi mã hiện đang thực hiện được hoàn thành và mọi thư đã thêm trước đó đã được xử lý.

gì đang xảy ra trong mã của bạn

Khi bạn gọi setTimeout ...

setTimeout(function() { 
    console.log('AAA'); 
}, 0); 

... nhắn được thêm vào hàng đợi với callback quy định. Phần còn lại của mã của bạn…

for (i = 0; i < 1000; i++) { 
    console.log('BBB'); 
} 
// etc. 

… tiếp tục thực hiện đồng bộ. Khi nó đã hoàn thành xong, vòng lặp sự kiện thăm dò hàng đợi tin nhắn cho tin nhắn tiếp theo và tìm thấy một cuộc gọi với cuộc gọi lại setTimeout của bạn, sau đó được xử lý (gọi lại được chạy).

Cuộc gọi lại chỉ được thực hiện sau mã thực hiện hiện tại đã kết thúc, bất kể mất bao lâu.

Đọc thêm

Để biết thêm chi tiết về các vòng lặp sự kiện, xem:

+1

*" (Lưu ý: điều này có nghĩa là độ trễ trong cuộc gọi setTimeout không phải là điều chắc chắn ...) "* Tôi chưa bao giờ xem xét điều này. Cảm ơn đã chỉ ra điều đó! –

Các vấn đề liên quan