JavaScript定時器實現的原理分析

來源:互聯網
上載者:User

標籤:不同   例子   看到了   任務   效果   很多   timeout   沒有   時間   

JavaScript中的定時器大家基本在平時的開發中都遇見過吧,但是又有多少人去深入的理解其中的原理呢?本文我們就來分析一下定時器的實現原理、定時器的妙用、定時器使用注意事項,有興趣的朋友可以看下

JavaScript中的定時器大家基本在平時的開發中都遇見過吧,但是又有多少人去深入的理解其中的原理呢?下面我們就來分析一下定時器的實現原理。

一、儲備知識

在我們在項目中一般會遇見過這樣的兩種定時器,第一種是setTimeOut,第二種是setInterval,這兩種定時器有如下的區別:

1、setTimeout允許設定一個逾時對象,逾時後執行這個對象,但是只執行一次,無周期

2、setInternval允許設定一個逾時對象,逾時後執行這個對象,周期等於逾時對象指定的時間,周期為無限迴圈

舉一個簡單的例子來說明一下:

?
12345678910111213 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>blog案例</title></head><body> <script type="text/javascript">  setTimeout("alert(‘this is test‘)",2000);  setInterval("console.log(‘demo‘);",1000); </script></body></html>

這個運行後的結果是彈出了一次對話方塊,然後在控制台可以看到每1秒鐘會向其中輸出demo字樣

二、定時器原理初識

那麼問題來了,如下的代碼啟動並執行時候會出現什麼情況呢?

?
12345678910111213 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>blog案例</title></head><body> <script type="text/javascript">  setTimeout("alert(‘定時器!‘)",0);  alert("測試") </script></body></html>

是先執行alert("測試"),還是先執行alert("定時器")呢,那麼我們就來運行一下吧!

運行後的結果是先彈出測試字樣的彈出框,然後才彈出定時器字樣的彈出框,為什麼會這樣呢?不是定時器的時間為0就即可執行嗎?

答案不是這樣的,因為JS眾所周知是單線程的,所以很多人會認為在上面的例子中會先阻塞等待定時器執行完成後再執行下面的語句,但是這個也就是單線程的一個缺陷之一吧,為瞭解決這個問題,引入了非同步機制。非同步機制主要是利用一個我們平時很少去關注的一個知識點——瀏覽器的多線程。究竟什麼是瀏覽器的多線程呢?

三、瀏覽器的多線程

 這裡我們就來講解一下,眾所周知,JS是單線程的,但是對於瀏覽器來說JS的執行只不過是在瀏覽器眾多現成中的一條,我們稱之為JS引擎線程。而瀏覽器的其他線程則是通過JS引擎線程在執行到某個特定的功能之後指定給瀏覽器的對應線程。具體的原理詳見圖示:

 從這張圖我們可以知道JS引擎線程首先執行回呼函數塊,然後是執行點擊事件回調,接著是執行定時器的線程,最後在執行其他的線程。

以下面的代碼我們來分析一下:

?
12 setTimeout("alert(‘定時器!‘)",0);alert("測試")

首先JS線程讀取到setTimeout定時器,這個時候就會執行瀏覽器的線程,然後跳過定時器繼續執行,這個時候你就看到了彈出框的內容為測試,然後因為定時器的時間為0,所以一執行定時器線程就會即可將彈出框為定時器字樣的任務添加到主線程(JS引擎線程)的隊列之後,等待JS引擎的調用,這個時候我們看到的結果是先彈出測試,然後再彈出定時器

另外我們要注意在HTML5規範中規定定時器的定時時間不能小於4ms,如果是小於4ms,則預設為4ms,所以在這個例子中的0,預設的是4ms,但是這個在不通過的瀏覽器中的表現是不同的,但是這個一般在項目中是沒有什麼印象的,這個只是僅做瞭解即可。

 好的我們將上面的代碼改寫成這樣,然後我們再來看看效果:

?
123456 <script type="text/javascript"> console.time("test"); setTimeout("for(var i=0;i<1000;i++)console.log(‘定時器!‘);",1000); console.log("測試"); console.timeEnd("test");</script>

    運行後的結果如下:

    這裡有幾個知識點:

1、console.time和console.timeEnd這兩個方法是可以擷取在其中間執行的語句所用的時間,我們可以知道test執行的時間在1ms左右,然而定時器的定時時間是在1000ms左右所以這兩個語句只能計算當前引擎的執行時間,換句話說就是在瀏覽器中的定時器模組的已耗用時間是這樣是沒法計算的

2、另外我們可以看到一個現象就是定時器在執行的時候不是一千個定時器的字樣全都一次性的列印出來,而是幾百幾百的增加,這個是為什麼呢?這裡就涉及到了另外的一個問題,如果是定時器的時間到了,但是定時器中的任務沒有執行完成這個時候會怎樣?

我們上面說過就是定時器的時間到了的情況下,就會向JS引擎線程新增工作,不論任務裡面的語句是否執行完成,都會像JS引擎線程隊列中添加,但是剩下的未執行完成的語句怎麼辦呢?

程式執行到了定時器任務的時候,就會先把已經在定時器模組執行過的語句載入一次,然後是繼續執行定時器模組的剩餘語句。(定時器模組向JS引擎中添加的任務相當於就是C語言中的一個指標,指向的是定時器模組)

所以,setTimeout我們可以定義為:

在指定時間內, 將任務放入事件隊列,等待js引擎空閑後被執行.

四、setInterval的使用

setInterval最基礎的使用方法是直接當一個迴圈定時器使用,這裡就不舉例說明

對於setInterval(fn, 100)容易產生一個誤區:並不是上一次fn執行完了之後再過100ms才開始執行下一次fn。 事實上,setInterval並不管上一次fn的執行結果,而是每隔100ms就將fn放入主線程隊列,而兩次fn之間具體間隔多久就不一定了,跟setTimeout實際延遲時間類似,和JS執行情況有關。具體的延遲效果與記憶體等因素有關。

五、定時器的可靠性

雖說定時器在大部分的情況下都是趨於穩定的,但是定時器在使用的時候也存在著一些誤差

如下所示:

?
1234567 <script type="text/javascript">  var time1 = new Date().getTime();  setInterval(function(){   var time2 = new Date().getTime();   console.log("setInterval執行的差值時間:"+(time2-time1));  },1000); </script>

啟動並執行結果如下:

我們基本可以看出定時器存在著一些小小的誤差就比如第一次的已耗用時間為1001ms比我們設定的時間多出了1ms,所以得出結論:定時器不是完全的可靠的,存在極小的誤差。這個還是在chrome瀏覽器上面測試的結果,換是在IE瀏覽器測試那又如何呢?

結果顯示,在IE瀏覽器下面的誤差更大

六、定時器的妙用

 定時器在項目中除了可以作為定時的作用外還可以用來做耗時代碼的最佳化:

 我們假設有這樣的一個情境,就是在某個頁面中要渲染50萬個節點,這個時候對於一般的項目中,直接渲染是不可取的,因為這個時候會佔用過多的記憶體,導致瀏覽器出現了卡死的狀態,使用者誤以為是頁面卡死而  直接關閉瀏覽器或者殺死進程,即使是使用者不關閉頁面這樣給使用者的體驗也是不好的,這個時候我們要怎樣來解決這個問題呢,我們可以利用定時器來最佳化這個問題首先我們可以把50萬個節點分成多組,每組渲染  的節點數不要過多,然後通過setInterval來進行迴圈這個既不阻塞JS引擎線程的運行,又不可以提高渲染的消耗時間。從而達到最終的最佳化渲染。

七、定時器使用注意事項

 如果是項目中有對個定時器的參與那麼記得在一個定時器執行結束的時候記得要調用clearInterval或clearTimeout這兩個方法來清除定時器,以免定時器之間互相干擾出現一些抓摸不定的現象

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的協助,如果有疑問大家可以留言交流,同時也希望多多支援指令碼之家!

原文連結:http://www.cnblogs.com/st-leslie/p/6082450.html

JavaScript定時器實現的原理分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.