標籤:bsp on() 產生 cti geo loop sign 設計 頁面
近期在複習JavaScript,看到setTimeout函數時。想起曾經剛學時,在一本書上看過setTimeout()裡的回呼函數執行的間隔時間有昌不是後面設定的值。曾經沒想太多。網上看了JS大神的解釋,整理記錄下JavaScript引擎的內部執行機制。
首先看一段小程式:
<script> alert('第1'); setTimeout(function(){alert('第2');}, 2000); alert('第3');</script>
輸出順序是:第1。第3,第2;再來看一段小程式:
<script> alert('第1'); setTimeout(function(){alert('第2')}, 0); alert('第3');</script>
輸出順序還是:第1,第3,第2。為什麼不是第1,第2,第3。setTimeout的間隔時間設定為0不就是馬上執行嗎?在此引出JavaScript的執行機制:Event Loop(貌似譯為事件輪詢)。
JavaScript的任務隊列
由於JavaScript是單線程的。全部的任務僅僅能是一個接一個的運行,可是當遇像IO這種讀取一些大檔案時就會出現後一個任務長時間處於等待狀態。要等到前一個任務運行完才幹開始後一個任務。
由於這樣。JavaScript也設計為主線程能夠先無論IO裝置,先運行後面的任務,等IO裝置返回了結果。再回去繼續運行。
因此。在JavaScript中,全部的任務能夠分為兩種:一是同步任務(synchronous);二是非同步任務(asynchronous)。
同步任務就是:在主線程上。必須等前一個任務運行完。才幹運行後一個任務;非同步任務則是:不進入主線程。而是進入“任務隊列”(task queue)的任務,主線程僅僅有在得到“任務隊列”的通知。某個非同步任務能夠運行,該非同步任務才會進入主線程運行。
事實上“任務隊列”就是一個事件的隊列。主線程讀取“任務隊列”,就是讀取裡面的事件。這些事件一般包含IO裝置的事件、點擊、滾動事件,凡是指定過回呼函數(callback)。這些事件發生時就會進入“任務隊列”。非同步任務必須指定回呼函數。主線程運行非同步任務,就是運行相應的回呼函數。
oText.innerText = '...';
比方在某一頁面中。運行了上面這一代碼後。DOM的內容會發生改變,接著系統觸發DOM Changed事件,產生非同步回調。回呼函數被加入到“任務隊列”中。
Event Loop
1.同步任務在主線程上運行會形成一個“運行棧”(execution context stack);
2.非同步任務在“任務隊列”裡有執行結果就會在“任務隊列”裡置一事件(Event)。
3.當“運行棧”中的同步任務都運行完後。“任務隊列”中有運行結果(事件,比方:Mouse Clicks、Key Presses、定時事件等)的非同步任務就會進入“運行棧”,開始運行;
主線程從“任務隊列”讀取事件的過程是不斷迴圈的,這樣的機制就稱為Event Loop。
Event Loop圖解:
僅僅有“運行棧”中任務運行完了,就會去讀取“任務隊列”,運行各事件相相應的回呼函數。
如今應該明確開篇中,為什麼setTimeout的間隔時間設定為0卻最後運行了吧,由於要等“運行棧”中的代碼運行完後,才會去運行“任務隊列”中的回呼函數。
Author:顧故
Sign:別輸給以前的自己
【JS】JavaScript引擎的內部執行機制