我第一次看到他事件環(event-loop)的時候,我是一臉懵,這是什麼鬼,是什麼循環嗎,爲何event還要loop,不是都是一次性的嗎?node
瀏覽器中和nodejs環境中的事件環是有一些區別的,這裏我只研究了nodejs環境,小黑框狀況下的事件環。瀏覽器
這裏的事件環並非指單獨一件事件的循環,而是咱們寫的不少不少的事件按照必定地規則排着隊去執行,而後隊列清空後繼續排隊,就是事件環。bash
事件環很複雜,這裏我只有能力解釋事件環中的幾個點:異步
nodejs中將eventloop分紅了:socket
這邊咱們專一於timers、poll和check這三個階段。其餘的咱們用的很少。ide
這個階段,只執行setTimeout和setInterval,可是他們的callback不會執行,而是推到宏任務的隊列之中。oop
這個階段,會先執行符合條件的微任務,好比Promise的異步完成,若是是setImmediate,則只會執行,不執行他的callback,而後執行定時器的callback,好比timeout。這裏會適當得暫停一會,看看會不會有新任務進入隊列。若是有setImmediate的callback則進入check 階段,不然回到timer繼續新一輪循環。ui
當poll階段的隊列完成,則會輪到check,這時會執行setImmediate的callback。若是沒有須要關閉callbacks,那麼就回到timer繼續新一輪的循環。spa
從個人角度理解,就是一個正常的task,原本在一個線程中能夠毫無波折地一個接着一個運行到最後,奈何每一個宏任務執行以後都有可能產生一些微任務,所以很不幸,這些宏任務就要排在這些微任務以後了。線程
宏任務表明:script(總體代碼),setTimeout,setImmediate。
/**
output:
我先走一步
你太慢了,我插個隊
老司機,等等我
*/
setTimeout(()=>{
console.log("我先走一步")
})
setTimeout(()=>{
console.log("老司機,等等我")
},10)
setImmediate(()=>{
console.log("你太慢了,我插個隊")
})
複製代碼
劃重點
setTimeout和setImmediate,觸發的階段不一樣,所以callback執行時間也不一樣。可是若是setTimeout的時間過長,那麼系統會先執行setImmediate,而後等下一輪詢中,若是setTimeout到時間了,那麼就運行setTimeout的callbacks。
就是宏任務執行時,產生的新的小任務,好比異步,此類任務稱之爲微任務,通常在當前宏任務執行完以後「插隊」執行。
微任務表明:process.nextTick, Promise(原生)。
劃重點
雖然process.nextTick和Promise都是微任務,可是他們的執行的前後順序是不同的。不管誰的代碼先執行,等到了poll階段,二者都是可運行的狀態時,都是nextTick先於Promise執行。
/**
output:
本宮始終是你望成莫及的
總有一日,我會上位
*/
Promise.resolve().then(()=>{
console.log("總有一日,我會上位")
})
process.nextTick(()=>{
console.log("本宮始終是你望成莫及的")
})
複製代碼
後記:
我只寫了我對於eventloop的理解,可是還有不少雲裏霧裏的地方,寫出來的只是我理解的。