之前一直停留在主線程先執行,異步後執行的淺理解中,後來隨着不斷的學習,才漸漸意識到這裏面還是有點複雜的,不過我不打算寫很多。一幅圖來說明這個複雜的關係
processTick可理解爲node中的延時器。
接下來看一道題目
// 1 7 6 8 2 4 9 11 3 10 5 12 console.log('1'); // 1 setTimeout(function() { // 2 console.log('2'); process.nextTick(function() { // 3 console.log('3'); }) new Promise(function(resolve) { // 4 console.log('4'); resolve(); }).then(function() { console.log('5') }) }) // 6 process.nextTick(function() { console.log('6'); }) // 7 8 new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { // 9 console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { // 11 console.log('11'); resolve(); }).then(function() { console.log('12') }) })
根據上述的知識,可以得出下面的分析,進而得出答案
首先宏script部分 :1 7 ,毋庸置疑,如果你說new Promise( )怎麼就立即執行了,先去看看new做的四件事 執行了還不算完,還要把異步的寫進事件列表,進而註冊事件隊列
現在宏事件隊列有 : 兩個setTimeout裏的異步函數 還有一個process.nextTick()的微異步函數,外加一個then也有一個
執行當前所有的微任務裏的任務 : 6 8
執行當前所有宏任務隊列裏的任務 : 首先執行第一個setTimeout裏的異步 : 打印 2 ,又一個process.nextTick()微任務存到隊列中(爲了省事省去了到事件列表的步驟),打印4,又一個微任務then中的異步函數存到隊列中
執行第二個setTimeout裏的異步函數 : 打印 9,又一個process.nextTick()微任務存到隊列中,打印11,又一個微任務then中的異步函數存到隊列中
最後執行微任務 : 此時微任務裏有兩個process.nextTick()微任務,兩個then微任務,所以首先把兩個process.nextTick()微任務執行完再去執行兩個then 結果打印 3 10 5 2
總結 : 事件循環 , 宏微交替
最後附上我學習js運行機制的地址:https://juejin.im/post/59e85eebf265da430d571f89,寫的真的好,耐心看,但是在那篇博客在宏微交替的理解上有偏差,或許是因爲node版本不一樣了,我這是沒問題的
注意:上文僅針對node環境下,瀏覽器環境下運行機制簡單說一下:首先宏微任務的分配沒有改變,但是執行的時候是抓一個宏,執行全部微任務,再去抓一個宏任務,執行所有微任務,有點差異。