Có hai loại (hầu hết được sử dụng) chức năng hẹn giờ trong javascript setTimeout
và setInterval
( loại khác )
Cả hai phương pháp này đều có cùng chữ ký. Họ lấy chức năng gọi lại và trì hoãn thời gian làm tham số.
setTimeout
chỉ thực hiện một lần sau khi trì hoãn trong khi setInterval
tiếp tục gọi hàm gọi lại sau mỗi milisec trễ.
cả hai phương thức này đều trả về một định danh số nguyên có thể được sử dụng để xóa chúng trước khi hết giờ.
clearTimeout
và clearInterval
cả hai phương thức này đều nhận một số nhận dạng nguyên được trả về từ các hàm trên setTimeout
vàsetInterval
Thí dụ:
setTimeout
alert("before setTimeout");
setTimeout(function(){
alert("I am setTimeout");
},1000); //delay is in milliseconds
alert("after setTimeout");
Nếu bạn chạy đoạn mã trên, bạn sẽ thấy nó cảnh báo before setTimeout
và after setTimeout
cuối cùng nó sẽ cảnh báo I am setTimeout
sau 1 giây (1000ms)
Những gì bạn có thể nhận thấy từ ví dụ là setTimeout(...)
không đồng bộ, điều đó có nghĩa là nó không đợi bộ đếm thời gian bị trôi qua trước khi đi đến câu lệnh tiếp theo, tức làalert("after setTimeout");
Thí dụ:
xác định
alert("before setInterval"); //called first
var tid = setInterval(function(){
//called 5 times each time after one second
//before getting cleared by below timeout.
alert("I am setInterval");
},1000); //delay is in milliseconds
alert("after setInterval"); //called second
setTimeout(function(){
clearInterval(tid); //clear above interval after 5 seconds
},5000);
Nếu bạn chạy mã ở trên, bạn sẽ thấy nó cảnh báo before setInterval
và after setInterval
cuối cùng nó sẽ cảnh báo I am setInterval
5 lần sau 1 giây (1000ms) vì setTimeout xóa bộ hẹn giờ sau 5 giây hoặc cứ sau 1 giây bạn sẽ nhận được cảnh báo I am setInterval
Vô hạn.
Làm thế nào trình duyệt nội bộ làm điều đó?
Tôi sẽ giải thích ngắn gọn.
Để hiểu rằng bạn phải biết về hàng đợi sự kiện trong javascript. Có một hàng đợi sự kiện được thực hiện trong trình duyệt. Bất cứ khi nào một sự kiện được kích hoạt trong js, tất cả các sự kiện này (như nhấp chuột, v.v.) sẽ được thêm vào hàng đợi này. Khi trình duyệt của bạn không có gì để thực thi, nó sẽ lấy một sự kiện từ hàng đợi và thực thi từng cái một.
Bây giờ, khi bạn gọi setTimeout
hoặc setInterval
cuộc gọi lại của bạn được đăng ký vào một bộ đếm thời gian trong trình duyệt và nó được thêm vào hàng đợi sự kiện sau khi hết thời gian nhất định và cuối cùng javascript lấy sự kiện từ hàng đợi và thực thi nó.
Điều này xảy ra như vậy, bởi vì công cụ javascript là một luồng và chúng chỉ có thể thực thi một điều duy nhất tại một thời điểm. Vì vậy, họ không thể thực thi các javascript khác và theo dõi bộ đếm thời gian của bạn. Đó là lý do tại sao các bộ hẹn giờ này được đăng ký với trình duyệt (trình duyệt không phải là một luồng) và nó có thể theo dõi bộ đếm thời gian và thêm một sự kiện trong hàng đợi sau khi hết giờ.
điều tương tự chỉ xảy ra setInterval
trong trường hợp này, sự kiện được thêm vào hàng đợi một lần nữa sau khoảng thời gian được chỉ định cho đến khi nó bị xóa hoặc làm mới trang trình duyệt.
Ghi chú
Tham số độ trễ bạn chuyển đến các hàm này là thời gian trễ tối thiểu để thực hiện gọi lại. Điều này là do sau khi hết giờ, trình duyệt thêm sự kiện vào hàng đợi để được thực thi bởi công cụ javascript nhưng việc thực hiện cuộc gọi lại phụ thuộc vào vị trí sự kiện của bạn trong hàng đợi và vì công cụ là một luồng, nó sẽ thực hiện tất cả các sự kiện trong hàng đợi từng người một.
Do đó, cuộc gọi lại của bạn đôi khi có thể mất nhiều thời gian hơn thời gian trì hoãn được chỉ định để được gọi đặc biệt khi mã khác của bạn chặn luồng và không cho nó thời gian để xử lý những gì có trong hàng đợi.
Và như tôi đã đề cập javascript là một chủ đề duy nhất. Vì vậy, nếu bạn chặn các chủ đề trong thời gian dài.
Thích mã này
while(true) { //infinite loop
}
Người dùng của bạn có thể nhận được một trang thông báo không phản hồi .
setTimeout(function(){/*YourCode*/},1000);