事件循環(event loop),是JavaScript用來解決因爲單線程阻塞形成執行效率低下的機制,也就是咱們常說的異步
的基石。在不一樣的JavaScript宿主環境,Event Loop
有着不一樣的模型。node
任務隊列是用來存放異步任務的回調,是一種先進先出的線性結構。因爲異步任務之間並不相同,任務隊列也由多個隊列組成。面試
流程圖大體以下: chrome
在node中,事件循環表現出的狀態與瀏覽器中大體相同。不一樣的是node中有一套本身的模型。node中事件循環的實現是依靠的libuv引擎。咱們知道node選擇chrome v8引擎做爲js解釋器,v8引擎將js代碼分析後去調用對應的node api,而這些api最後則由libuv引擎驅動,執行對應的任務,並把不一樣的事件放在不一樣的隊列中等待主線程執行。 所以實際上node中的事件循環存在於libuv引擎中。api
NodeJS的Event Loop中,執行宏隊列的回調任務有6個階段,以下圖:瀏覽器
各個階段執行的任務以下:異步
timers 階段會執行 setTimeout 和 setInterval 回調,而且是由 poll 階段控制的。socket
執行除了close事件的callbacks、被timers設定的callbacks、setImmediate()設定的callbacks這些以外的callbacksoop
僅node內部使用post
poll 是一個相當重要的階段,這一階段中,系統會作兩件事情線程
進入該階段時若是沒有設定了 timer:
setImmediate
回調須要執行,poll 階段會中止而且進入到 check 階段執行回調setImmediate
回調不須要執行,會等待回調被加入到隊列中並當即執行回調,這裏一樣會有個超時時間設置防止一直等待下去若是設定了 timer:
check 階段執行 setImmediate的回調
執行socket.on('close', ....)這些callbacks
對於 microtask
來講,它會在以上每一個階段完成前清空microtask 隊列