文章出處

一、前言                              

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

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

 

二、同步和異步調用                        

  由于JavaScript是通過異步調用來盡早釋放UI線程,因此我們先要了解同步和異步執行的具體含義:

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

  同步執行:執行后等待直到獲取執行結果;

  異步執行:執行后不等待,而是通過一系列手段(輪詢、事件監聽和event loop等)獲取執行結果,而在執行后和獲取結果前的那段時間可以介入其他任務操作。  

 

二、setTimeout(handler, 0)的問題                

  由于setTimeout存在時間精度,因此setTimeout(handler,0)中setTimeout事件插入事件隊列的延時必定大于0ms,而handler的執行延時則更大了。具體為IE5~8和不插電源的IE9的時間精度為15.6ms,插電源的IE9和其他瀏覽器則為4ms。

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

    

三、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事件先加入事件隊列。

 

四、總結                            

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

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

 

五、參考                            

  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/


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()