javascript 運行機制

macro-task(宏任務):包括整體代碼script,setTimeout,setInterval

micro-task(微任務):Promise,process.nextTick、

https://juejin.im/post/59e85eebf265da430d571f89#heading-4     原文

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})複製代碼

第一輪事件循環流程分析如下:

  • 整體script作爲第一個宏任務進入主線程,遇到console.log,輸出1。
  • 遇到setTimeout,其回調函數被分發到宏任務Event Queue中。我們暫且記爲setTimeout1
  • 遇到process.nextTick(),其回調函數被分發到微任務Event Queue中。我們記爲process1
  • 遇到Promisenew Promise直接執行,輸出7。then被分發到微任務Event Queue中。我們記爲then1
  • 又遇到了setTimeout,其回調函數被分發到宏任務Event Queue中,我們記爲setTimeout2
宏任務Event Queue 微任務Event Queue
setTimeout1 process1
setTimeout2 then1
  • 上表是第一輪事件循環宏任務結束時各Event Queue的情況,此時已經輸出了1和7。

  • 我們發現了process1then1兩個微任務。

  • 執行process1,輸出6。
  • 執行then1,輸出8。

好了,第一輪事件循環正式結束,這一輪的結果是輸出1,7,6,8。那麼第二輪時間循環從setTimeout1宏任務開始:

  • 首先輸出2。接下來遇到了process.nextTick(),同樣將其分發到微任務Event Queue中,記爲process2new Promise立即執行輸出4,then也分發到微任務Event Queue中,記爲then2
宏任務Event Queue 微任務Event Queue
setTimeout2 process2
  then2
  • 第二輪事件循環宏任務結束,我們發現有process2then2兩個微任務可以執行。
  • 輸出3。
  • 輸出5。
  • 第二輪事件循環結束,第二輪輸出2,4,3,5。
  • 第三輪事件循環開始,此時只剩setTimeout2了,執行。
  • 直接輸出9。
  • process.nextTick()分發到微任務Event Queue中。記爲process3
  • 直接執行new Promise,輸出11。
  • then分發到微任務Event Queue中,記爲then3
宏任務Event Queue 微任務Event Queue
  process3
  then3
  • 第三輪事件循環宏任務執行結束,執行兩個微任務process3then3
  • 輸出10。
  • 輸出12。
  • 第三輪事件循環結束,第三輪輸出9,11,10,12。

整段代碼,共進行了三次事件循環,完整的輸出爲1,7,6,8,2,4,3,5,9,11,10,12。
(請注意,node環境下的事件監聽依賴libuv與前端環境不完全相同,輸出順序可能會有誤差)

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章