JS魔法堂:初探傳說中的setImmediate函數

1、前言                              html

   因爲JavaScript程序爲單線程,所以在執行長時間的操做時(如循環和遞歸操做)到致使UI線程長期被阻塞,沒法響應用戶操做請求(如點擊按鈕等),讓用戶體驗大打折扣。因而想到將一個長時間操做切片成N個小操做並異步執行,例如jsDeferred中的 Deferred.repeat函數 就提供這樣的解決辦法,其實質就是經過 setTimeout事件 或 script元素 的 onerror/onload事件 來異步調用這些小操做,從而儘早釋放UI線程。git

   從IE10開始引入了setImmediate接口來代替setTimeout來完成上述功能,下面將記錄該接口的資訊,因爲內容會涉及到event loop、調用棧等知識,而我對相關內容瞭解仍不全面,所以下面的內容如有紕漏請各位指正,謝謝!github

 

2、同步和異步調用                        瀏覽器

  因爲JavaScript是經過異步調用來儘早釋放UI線程,所以咱們先要了解同步和異步執行的具體含義:網絡

  任務的執行實質上分爲兩步:①.執行,②.獲取執行結果。異步

  同步執行:執行後等待直到獲取執行結果;函數

  異步執行:執行後不等待,而是經過一系列手段(輪詢、事件監聽和event loop等)獲取執行結果,而在執行後和獲取結果前的那段時間能夠介入其餘任務操做。  oop

 

2、setTimeout(handler, 0)的問題                測試

  因爲setTimeout存在時間精度,所以setTimeout(handler,0)中setTimeout事件插入事件隊列的延時一定大於0ms,而handler的執行延時則更大了。具體爲IE5~8和不插電源的IE9的時間精度爲15.6ms,插電源的IE9和其餘瀏覽器則爲4ms。spa

  經微軟和Chrome團隊實驗所得下降時間精度將會大大縮短筆記本的續航時間,也是就說更耗電,所以即便瀏覽器廠商有能力縮短期精度,但基於多方面的考慮,依然保持上述的精度值。

    

3、setImmediate接口                     

  對於經過異步執行的手段對任務切片,因爲UI線程獲得釋放從而提升用戶體驗,但相對於採用同步執行,總體的任務執行時間較被拉長,所以咱們但願切片的小操做越快執行越好。而setImmediate接口則是爲此而生的。

   setImmediate(handler) 並不像 setTimeout(handler, 0) 由event loop檢測系統時間是否到點而後向事件隊列插入一個事件,而後調用事件的回調方法handler。而是監控UI線程的調用棧,一旦調用棧爲空則將handler壓棧。

   理論上經過setImmediate執行異步調用的延時必定比經過setTimeout的短,但事實又是如何呢?

   我在IE11上操做測試,setTimout的延時爲4ms左右,而setImmediate的延時爲2ms左右。

   注意:

     1. 經過setImmediate的異步調用的延時不是0ms哦!

     2. 並且有時候setImmediate的延時比setTimeout的多1~2ms哦!

     3. 並且setImmediate和setTimeout的延時均比img元素onerror事件的延時長哦!

  推測:

     1. 對於setImmediate的延時有時比setTimeout的要長,因爲setImmediate要先監控調用棧,若調用棧爲空才壓棧,那麼在壓棧以前event loop已經將setTimeout事件的回調函數壓棧了。

     2. 對於二者均比img元素onerror事件的長,因爲設置img.src後立刻發起請求(不必定爲網絡IO)當加載失敗時onerror事件則會比setTimeout事件先加入事件隊列。

 

4、總結                            

  本文內容紕漏之處請各位指正,謝謝!

  尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/4151595.html ^_^肥仔John

 

5、參考                            

  http://developer.51cto.com/art/201109/292720.htm

  http://msdn.microsoft.com/library/ie/hh920766.aspx

  https://github.com/yuzujs/setimmediate

  http://www.nczonline.net/blog/2011/09/19/script-yielding-with-setimmediate/

相關文章
相關標籤/搜索