瀏覽器線程與setTimeout(...,0)

clipboard.png

瀏覽器三個常駐線程

瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程: javascript

javascript引擎線程

javascript引擎是基於事件驅動單線程執行的,JS引擎一直等待着任務隊列中任務的到來,而後加以處理,瀏覽器不管何時都只有一個JS線程在運行JS程序php

GUI渲染線程

GUI渲染線程負責渲染瀏覽器界面,當頁面須要重繪(repaint)或因爲某種操做引起的迴流(reflow)時,該線程就會執行.可是,須要注意的是GUI渲染線程javascript引擎線程互斥的,當js引擎執行時,GUI線程就會被掛起,GUI更新會被保存在一個隊列中,等待js引擎空閒時當即被執行.html

事件觸發線程

事件觸發線程,當一個事件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其餘線程如鼠標點擊、AJAX異步請求等,但因爲JS的單線程關係全部這些事件都得排隊等待JS引擎處理
參考:
JavaScript能否多線程? 深刻理解JavaScript定時機制java


到這裏, 就要說另外一個問題, js的異步問題瀏覽器

setTimeout(...,0)

在js中,咱們經常使用setTimeout(function(){},0)的方式來處理js的異步.
炒個栗子多線程

console.log(1);
setTimeout(function(){console.log(2)},0);
console.log(3);

輸出: 1 , 3, 2
不信點我試試
setTimeout(..) 並無把你的回調函數掛在事件循環隊列中。它所作的是設 定一個定時器。
當定時器到時後,環境會把你的回調函數放在事件隊列中,若是這時候事件循環中已經有 20 個項目了會怎樣呢?你的回調就會等待,定時器只能確保你的回調函數不會在指定的 時間間隔以前運行,但可能會在那個時刻運行,也可能在那以後運行,要根據事件隊列的 狀態而定(PS: 這就是形成定時器不許確的原因)。異步

setTimeout(..0)(hack)進行異步調度,基本上它的意思就是把這個函數插入到當前事件循環隊列的結尾處函數


正常狀況下javascript都是按照順序執行的。可是咱們可能讓該語句後面的語句執行完再執行自己,先執行全部的同步再執行全部的異步.
炒個栗子spa

for(var i = 0;i < 3;i++){
setTimeout(function(){
alert('知乎');
},0)
alert(i);
}

點我看看
輸出: 0 1 2 知乎 知乎 知乎
setTimeout第二個參數爲0表示當即執行。當使用這個方法的時候,瀏覽器會另起一個線程,來執行setTimeout裏面的函數,而原有的線程繼續執行, 待原有線程結束後,在執行後面的線程(js單線程)。.net

相關文章
相關標籤/搜索