我已經迷失在事件環(event-loop)中了【Nodejs篇】

我第一次看到他事件環(event-loop)的時候,我是一臉懵,這是什麼鬼,是什麼循環嗎,爲何event還要loop,不是都是一次性的嗎?node

瀏覽器中和nodejs環境中的事件環是有一些區別的,這裏我只研究了nodejs環境,小黑框狀況下的事件環。瀏覽器

這裏的事件環並非指單獨一件事件的循環,而是咱們寫的不少不少的事件按照必定地規則排着隊去執行,而後隊列清空後繼續排隊,就是事件環。bash

事件環很複雜,這裏我只有能力解釋事件環中的幾個點:異步

node.js中對於事件環的解釋

nodejs中將eventloop分紅了:socket

  • timers: 定時器setTimeout執行,將callback加入隊列中。
  • pending callbacks: 一些I/O的callback,推遲到下一次循環中執行。
  • idle, prepare: 內部的一些事件。
  • poll: 定時器的callback執行,setImmediate執行,微任務執行。
  • check: setImmediate的callback執行。
  • close callbacks: 一些callbacks的關閉,如socket。

這邊咱們專一於timers、poll和check這三個階段。其餘的咱們用的很少。ide

timers、poll、check階段

  • timers

這個階段,只執行setTimeout和setInterval,可是他們的callback不會執行,而是推到宏任務的隊列之中。oop

  • poll

這個階段,會先執行符合條件的微任務,好比Promise的異步完成,若是是setImmediate,則只會執行,不執行他的callback,而後執行定時器的callback,好比timeout。這裏會適當得暫停一會,看看會不會有新任務進入隊列。若是有setImmediate的callback則進入check 階段,不然回到timer繼續新一輪循環。ui

  • check

當poll階段的隊列完成,則會輪到check,這時會執行setImmediate的callback。若是沒有須要關閉callbacks,那麼就回到timer繼續新一輪的循環。spa

宏任務 vs 微任務

  • 宏任務

從個人角度理解,就是一個正常的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的理解,可是還有不少雲裏霧裏的地方,寫出來的只是我理解的。

相關文章
相關標籤/搜索