轉自前端
https://juejin.im/post/59e85eebf265da430d571f89
導圖要表達的內容用文字來表述的話:node
同步和異步任務分別進入不一樣的執行"場所",同步的進入主線程,異步的進入Event Table並註冊函數。 當指定的事情完成時,Event Table會將這個函數移入Event Queue。 主線程內的任務執行完畢爲空,會去Event Queue讀取對應的函數,進入主線程執行。 上述過程會不斷重複,也就是常說的Event Loop(事件循環)。
包括總體代碼script,setTimeout,setInterval
Promise.then,Promise.catch, process.nextTick
注意:
1.
promise是當即執行的,它建立的時候就會執行,不存在將promise推入微任務中的說法;
resolve()是用來表示promise的狀態爲fullfilled,至關於只是定義了一個有狀態的Promise,可是並無調用它;
promise調用then的前提是promise的狀態爲fullfilled;
只有promise調用then的時候,then裏面的函數纔會被推入微任務中
2.
script標籤中的console.log()會當即執行
分析:promise
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') }) })
第一輪事件循環流程分析以下:異步
console.log
,輸出1。setTimeout
,其回調函數被分發到宏任務Event Queue中。咱們暫且記爲setTimeout1
。process.nextTick()
,其回調函數被分發到微任務Event Queue中。咱們記爲process1
。Promise
,new Promise
直接執行,輸出7。then
被分發到微任務Event Queue中。咱們記爲then1
。setTimeout
,其回調函數被分發到宏任務Event Queue中,咱們記爲setTimeout2
。宏任務Event Queue | 微任務Event Queue |
---|---|
setTimeout1 | process1 |
setTimeout2 | then1 |
上表是第一輪事件循環宏任務結束時各Event Queue的狀況,此時已經輸出了1和7。函數
咱們發現了process1
和then1
兩個微任務。oop
process1
,輸出6。then1
,輸出8。好了,第一輪事件循環正式結束,這一輪的結果是輸出1,7,6,8。post
那麼第二輪事件循環從setTimeout1
宏任務開始:spa
process.nextTick()
,一樣將其分發到微任務Event Queue中,記爲process2
。new Promise
當即執行輸出4,then
也分發到微任務Event Queue中,記爲then2
。宏任務Event Queue | 微任務Event Queue |
---|---|
setTimeout2 | process2 |
then2 |
process2
和then2
兩個微任務能夠執行。process.nextTick()
分發到微任務Event Queue中。記爲process3
。new Promise
,輸出11。then
分發到微任務Event Queue中,記爲then3
。宏任務Event Queue | 微任務Event Queue |
---|---|
process3 | |
then3 |
process3
和then3
。整段代碼,共進行了三次事件循環,完整的輸出爲1,7,6,8,2,4,3,5,9,11,10,12。
(請注意,node環境下的事件監聽依賴libuv與前端環境不徹底相同,輸出順序可能會有偏差)線程