js執行機制
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執行機制