--- tags: node.js --- # Node.js event queue Node.js 當 main thread 執行結束後會進入 event queue 迴圈中。每次 event queue 迴圈中有下面 6 個階段,每個階段會執行它相應的 queue 內的 task,當它的 queue 內的 task 執行完畢後會執行完所有 `porcess.nextTick()` 放入 **nextTickQueue** 中的 task,接著再執行完 `Promise` 放入 **micro task queue** 中的 task,並且會等到 **nextTickQueue** 和 **micro task queue** 全部執行完畢後才會進入下個階段。 所以如果 `Promise` resolve 中會產生新的 `Promise` 或 `process.nextTick` 會呼叫新的 `process.nextTick` 則 **micro task queue** 階段就會一直執行下去而卡住 **event queue** 讓程式無法回應 request。 比方: ```javascript= const f = () => { process.nextTick(() => console.log(1)); Promise.resolve().then(() => console.log(2)); }; f(); Promise.resolve().then(f); ``` 會印出 `1221`,它的執行狀況是: 1. main thread 執行 `f()` 2. `f()` 內的 `process.nextTick(() => console.log(1));` 將 `console.log(1)` 放入 **nextTickQueue** 中 3. `f()` 內的 `Promise.resolve().then(() => console.log(2));` 將 `console.log(2)` 放入 **micro task queue** 中 4. main thread 執行 `Promise.resolve().then(f);` 將 `f()` 放入 **micro task queue** 中 5. main thread 結束,開始 even queue 6. timer 階段沒有 timer 所以結束 7. 開始執行 **nextTickQueue** 中的 task,印出 `1`,之後 **nextTickQueue** 沒有 task 8. 開始執行 **micro task queue** 印出 `2` 9. 第 2 個 task 執行 `f()` 10. `f()` 內的 `process.nextTick(() => console.log(1));` 將 `console.log(1)` 放入 **nextTickQueue** 中 11. `f()` 內的 `Promise.resolve().then(() => console.log(2));` 將 `console.log(2)` 放入 **micro task queue** 中 12. 結束後,因為步驟 11 所以 **micro task queue** 又有新的 task,因此執行 `console.log(2)` 印出 `2`,結束後 **micro task queue** 沒有 task 13. 這時會再回來檢查 **nextTickQueue**,因為步驟 10 所以有新的 task,執行 `console.log(1)` 印出 `1`,結束後 **nextTickQueue** 沒有 task 14. event queue 會來回在 **nextTickQueue** 和 **micro task queue** 內的 task 清空後檢查另一邊,直到 2 邊的 task 都完全清空後進到下個階段,所以下面程式會無窮來回執行 **nextTickQueue** 和 **micro task queue** 內的 task: ```javascript= const f = (g) => process.nextTick(() => {console.log('nextTick'); g(f)}); const g = (f) => Promise.resolve().then(() => {console.log('promise'); f(g)}); f(g); g(f); ``` timer pending idle, prepare poll check closed