1. 程式人生 > >js執行機制

js執行機制

分發 sleep 代碼執行 過程 rom spa set 是否 引擎

1. 關於javascript

js是一門單線程語言,一切js版的‘多線程’都是用單線程模擬起來的。

2. js事件循環

將任務分為2類:同步任務、異步任務

技術分享圖片

同步任務進入主線程,異步任務進入Event Table並註冊函數

當指定的事件完成時,Event Table會將這個函數移入Event Queue

主線程內的任務執行完畢為空後,會去Event Queue讀取對應的函數,進入主線程運行

以上過程會不斷的重復,即Event Loop事件循環

js引擎存在monitoring process進程,會持續不斷的檢查主線程執行棧是否為空

技術分享圖片

ajax進入Event Table,註冊回調函數success

執行console.log(‘代碼執行結束’)

ajax事件完成後,回調函數success進入event Queue

主線程從Event Queue讀取回調函數success並執行

3. setTimeout 異步任務

技術分享圖片

task()進入Event Table並註冊,計時開始

執行sleep()

3秒到了,計時事件完成,task()進入Event Queue,此時sleep()仍在執行

sleep()執行完畢

task()從Event Queue進入主線程並執行

setTimeout(fn,0)的含義是,指定某個任務在主線程最早可得的空閑執行,不用再等多少秒,只要主線程執行棧內的同步任務全部執行完就可以馬上執行

4. setInterval

setInterval會每隔指定時間將註冊的函數置入Event Queue

setInterval(fn,ms)不是每過ms秒就執行一次fn,而是每過ms秒,就會有fn進入Event Queue

一旦setInterval的回調函數fn執行時間超過了延遲時間ms,那麽就完全看不出來有時間間隔了

5. Promise與process.nextTick(callback)

宏任務 整體代碼script setTimeout setInterval

微任務 Promise process.nextTick

不同類型的任務會進入不同的Event Queue

技術分享圖片

技術分享圖片

先遇到setTimeout,將其回調函數註冊後分發到宏任務Event Queue

接下來遇到Promise,new Promise立即執行,then函數分發到微任務Event Queue

遇到console.log(‘console’)立即執行

第一次宏任務執行結束,查看微任務,發現了then,執行

第一輪事件循環結束,開始下一輪

第二輪,發現了宏任務Event Queue中的setTimeout立即執行

結束

6. 復雜的例子

技術分享圖片

技術分享圖片

第一輪事件循環Event Loop

console.log(‘1’);

遇到setTimeout,將其回調函數分發到宏任務Event Queue中,記為setTimeout1

遇到process.nextTick(),其回調函數被分發到微任務Event Queue中,記為process1

遇到Promise,輸出7,then被分發到微任務Event Queue,記為then1

又遇到setTimeout,其回調函數被分發到宏任務Event Queue中,記為setTimeout2

技術分享圖片

第一輪宏任務執行結束,開始執行微任務,輸出6和8

第一輪事件循環輸出1 7 6 8

第二輪事件循環Event Loop

宏任務setTimeout1:

首先輸出2

process.nextTick()分發到微任務EventQueue,記為process2

new Promise立即執行,輸出4

then分發到微任務Event Queue,記為then2

技術分享圖片

第二輪宏任務執行完畢,開始執行微任務,輸出3和5

第二輪事件結束,輸出2 4 3 5

第三輪事件循環Event Loop

宏任務setTimeout2:

輸出9

process.nextTick()分發到微任務EventQueue,記為process3

then分發到微任務Event Queue,記為then3

技術分享圖片

第三輪宏任務執行完畢,開始執行微任務,輸出10和12

第三輪事件結束,輸出9 10 12

7. 總結

js是一門單線程語言

Event Loop是js的執行機制

js執行機制