1. 只有一個主線程,node開始執行腳本時,會先進事件循環初始化(同步任務,發出異步請求,規劃定時器生效時間,執行promise.nextTick等),這時事件循環還未開始。node
nodejs運行機制:git
- V8引擎解析js腳本
- 解析後的代碼調用Node API
- libuv庫負責Node API的執行,它將不一樣的任務分配給不一樣的線程,造成一個Event Loop,以異步的方式將任務的執行結果返回給V8引擎
- V8引擎再將結果返回給用戶
2. nodejs每一輪事件循環的六個階段(事件循環會無限次執行,直到異步任務的回調函數隊列清空纔會中止執行):github
- timers(處理setTimeout和setInterval的回調函數)
- I/O callbacks(除了setTimeout、setInterval、setImmediate、用於關閉請求的回調函數)
- idle,prepare(libuv內部使用)
- poll(等待還未返回的I/O事件)
- check(setImmediate)
- close callbacks(執行關閉請求的回調,如socket.on('close', ...))
3. setTimeout和setImmediate:promise
因爲setTimeout第二個參數默認爲0,可是加上node作不到真正的0ms,最少也須要1s;因此實際執行進入事件循環後,若是沒到1ms,那麼timers階段就會跳過進入check階段,因此執行順序不肯定。異步
4. 異步任務分兩種:socket
本輪循環:promise.nextTick、promise的回調函數函數
次輪循環:setTimeout、setInteval、setImmediate的回調函數oop
5. 多個process.nextTick語句老是在當前"執行棧"一次執行完,多個setImmediate可能則須要屢次loop才能執行完;線程
6. 爲何process.nextTick 永遠大於 promise.then?由於Node中,_tickCallback在每一次執行完TaskQueue中的一個任務後被調用,而這個_tickCallback中實質上幹了兩件事:隊列
- nextTickQueue中全部任務執行掉(長度最大1e4,Node版本v6.9.1)
- 第一步執行完後執行_runMicrotasks函數,執行microtask中的部分(promise.then註冊的回調)