JavaScript
提供定時執行代碼的功能,叫作定時器(timer),主要由setTimeout()
和setInterval()
這兩個函數來完成。它們向任務隊列添加定時任務。在瞭解定時器前,你首頁也要對事件循環機制有必定的瞭解。能夠先閱讀這篇文章Js事件循環(Event Loop)機制。git
更多優質文章請猛戳GitHub博客,歡迎帥哥美女前來Star!!!github
定時器是一種異步任務,一般瀏覽器都有一個獨立的定時器模塊,定時器的延遲時間就由定時器模塊來管理,當某個定時器到了可執行狀態,就會被加入主線程隊列。瀏覽器
定時器的運行機制,是將指定的代碼移出本輪事件循環,等到下一輪事件循環,再檢查是否到了指定時間。若是到了,就執行對應的代碼;若是不到,就繼續等待。bash
因爲JS
的單線程特性,定時器提供了一種跳出單線程限制的方法,即讓一段代碼在必定毫秒以後,再異步執行。異步
setTimeout
函數用來指定某個函數或某段代碼,在多少毫秒以後執行。它返回一個整數,表示定時器的編號,之後能夠用來取消這個定時器。函數
var timer = setTimeout(func|code, delay);
clearTimeout(timer);
複製代碼
setTimeout
接受兩個參數:oop
func|code:
是將要推遲執行的函數名或者一段代碼。delay:
是推遲執行的毫秒數。clearTimeout():
是取消對應的定時器的函數。除了前兩個參數,setTimeout
還容許更多的參數。它們將依次傳入推遲執行的函數(回調函數)。post
舉個栗子:ui
setTimeout(function (a,b) {
console.log(a + b);
}, 1000, 1, 1);
複製代碼
setInterval
函數的用法與setTimeout
徹底一致,區別僅僅在於setInterval
指定某個任務每隔一段時間就執行一次,也就是無限次的定時執行。spa
var timer = setInterval(function() {
console.log(2);
}, 1000)
clearInterval(timer)
複製代碼
上面代碼中,每隔1000毫秒就輸出一個2,會無限運行下去,直到關閉當前窗口。clearInterval
函數是用來取消對應的定時器的。其餘的跟setTimeout
基本同樣。
定時器不是JavaScript的一項功能,而是做爲對象和方法的一部分,在瀏覽器中使用。也就是說,在非瀏覽器環境中使用JavaScript,極可能定時器不存在來。
咱們都知道JavaScript
是單線程的,這也決定了在異步事件(鼠標單擊、定時器等)程序的處理中,在線程中沒有代碼的時候纔會執行。即處理程序須要排隊執行,且不會被其餘處理程序中斷。
下面經過例子來了解定時器的詳細機制:
0ms
時,處啓動一個10ms
延遲的定時器,以及一個10ms
間隔定時器。6ms
時,觸發鼠標點擊事件。10ms
時,定時器和第一個間隔定時器都過時了(因爲主程序還在執行,因此定時器仍然在排隊,等待空閒在執行)。18ms
時,主線程執行完畢,開始執行隊列裏面的事件,隊列裏面如今有鼠標單擊事件、setTimeout
定時器和setInterval
定時器。20ms
時,因爲隊列裏面有setInterval
定時器,因此第二個到期的間隔定時器就會做廢處理。28ms
時,單擊事件執行完成,而且在10ms就應該執行的setTimeout
定時器,如今纔開始執行。30ms
時,第三個setInterval
定時器到期,因隊列中有間隔定時器,因此第三個也做廢。34ms
時,setTimeout
定時器執行完成,開始執行setInterval
,但因爲第一個間隔定時器在42ms時結束,因此40ms時,到期的第二個間隔定時器,又要進行排隊等待。47ms
時,因爲第二個setInterval
能夠在第三個間隔定時器50ms到期時執行完,因此不須要排隊直接執行。根據上面的流程進行小結:
事件排隊:
同時發生了這麼多事情,因爲js的單線程特性,當線程正在執行狀態,有異步事件觸發時,它就會排隊,而且在線程空閒時才進行執行。而且依照先進先出的順序執行(先排隊的先執行)。setInterval調用被廢棄:
在線程被佔用的狀況下,而且隊列中已經有setInterval
在排隊,則下一個到期的setInterval
會被廢棄。定時器沒法保證準時執行回調函數:
在主線程尚未結束,即便定時器時間到期仍然不會執行,必須等到主程序同步代碼所有執行完。setTimeout和setInterval的區別:
其最主要的區別是功能上的區別,setTimeout
只延遲執行一次,setInterval
按時間週期性的執行。其餘相關知識:
15ms
以上。即便設置了時間,若是使用不當的話,定時器仍是不會保證準時執行回調函數。而經過本文,相信你之前對定時器出現過相似問題有了必定的瞭解。但願你們熟練理解原理,你們加油!!