setTimeout原理


setInterval和setTimeout是前端開發中經常會用到的定時器,下面對其原理進行一下分析。

 

javascript是單線程的,一個javascript運行時包含了一個待處理的消息隊列,每條消息都代表要運行的函數。當調用棧為空時,會從隊列里取出條消息進行處理。

setTimeout方法包含兩個參數,第一個參數為一個函數或者一個會作為eval()方法參數的js代碼字符串,第二個參數為以毫秒為單位的時間。該方法的實際作用即:在一定時間之后,把一個函數加入消息隊列末尾。如果這個時間點消息隊列中還存在其他消息,那么該函數會在排在他之前的消息都執行完之后再開始執行。所以,這個時間會小於等於該函數開始運行的時間。

 

如上圖所示,函數a,b,c執行時間均為300ms,a在執行setTimeout時開始執行。在400ms之后,c加入了消息隊列,但此時調用棧中函數b仍在執行,c只能等b執行完之后才能開始執行,所以c從加入隊列之后第600ms才開始執行。

 

 1 setTimeout(function() {
 2     console.timeEnd('setTimeout實際等待時間:');
 3 },1000)
 4 console.time('setTimeout實際等待時間:');
 5 
 6 console.time("執行循環時間:");
 7 for (let i = 0; i < 10000; i++) {
 8     console.log(i);
 9 }
10 console.timeEnd("執行循環時間:");

以上代碼,在開始時在消息隊列里加入一個函數,並開始計時。該函數被放在了隊列的末尾,排在循環之后。於是循環會先執行,在循環和console語句執行完之后,setTimeout中的函數才會被執行。把該段代碼該段代碼在chrome中執行,最后的結果如下圖:

 

可見,setTimeout中的函數是在循環及console函數執行完之后才開始執行。

 

我們有時會在代碼中看到如下代碼:

 setTimeout(func, 0)

現在我們就可以理解該函數的意思了。這個函數的作用就是把func函數放到隊列的末尾,在所有函數都執行完之后再執行。

1 setTimeout(function() {
2    console.log('setTimeout') 
3 })
4 console.log('test1');
5 console.log('test2');
6 
7 // test1
8 // test2
9 // setTimeout

 

 

setInterval函數的原理與setInterval是相同的,就不再贅述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM