[面試][後端]請簡述 Node.js 的 Event Loop
本文目錄
熟悉的起手式:「我方便問你一個 Node.js 核心的問題嗎?」
這是一個在了解後,無論面試還是工作,CP 值都很高的題目,建議讀者要真的融會貫通。
大綱
- 請簡述 Node.js 的 Event Loop
- 1.1 面試官為什麼會問?
- 1.2 面試官想從答案確認什麼?
- 1.3 筆者提供的簡答
- 回答問題所需具備的知識
- 2.1 Event Loop 執行的邏輯
- 2.2 用 Node.js 範例程式確認自己是否理解 Event Loop
- 2.3 解析 Node.js 範例程式執行順序
- 衍伸問題
- 3.1 可以簡述 Node.js 跟 JavaScript 的差異嗎?
- 3.2 readFile 和 createReadStream 函式的差異?
- 3.3 REPL 是什麼?
1. 請簡述 Node.js 的 Event Loop
1.1 面試官為什麼會問?
只要你的履歷上有 Node.js,10 間公司至少有 3 間會問這個常見面試題;而且問題的起手式出奇的一致:「我方便問你一個 Node.js 核心的問題嗎?」
1.2 面試官想從答案確認什麼?
- 你了解 Event Loop 對 Node.js 的重要性
- 你能大概說明 Event Loop 每個階段的任務
- 如果出白板題要你解釋程式執行的順序,你可以正確回答
1.3 筆者提供的簡答
Node.js 之所以高效,是因為採取單執行緒與 Event Loop 的概念;將所有需要等待結果、請求外部資源的函式,全部丟到 Event Loop 中等待;而 Event Loop 的邏輯是 Node.js 底層用 C 語言撰寫的 libuv 庫來運行的。
2. 回答問題所需具備的知識
2.1 Event Loop 執行的邏輯

- 了解 MacroTask 的 6 個階段
- Timer
等計時器(setTimeout、setInterval)的時間一到,會把他們的 callback 放在這裡等待執行。 - Pending callbacks
作業系統層級使用(ex:TCP errors、sockets 連線被拒絕)。 - Idle, Prepare
內部使用。 - Polling:
- 如果 Queue 不為空,依次取出 callback 函數執行,直到 Queue 為空或是抵達系統最大限制。
- 如果 Queue 為空但有設置「setImmediate」就進入 Check 階段。
- 如果 Queue 為空但沒有設置「setImmediate」就會在 Polling 階段等待,直到 Queue 有東西或是 Timer 時間抵達。
- Check
處理 setImmediate 的 callback。 - Close callbacks
處理關閉連線、檔案的 callback。
- Timer
Macrotask Queue 在 Evevnt Loop 優先層級較低,接下來介紹優先層級更高的兩個 Queue。
-
NextTick Queue 優先層級最高
「process.nextTick()」的 callback 可以隨意插隊;只要這個 Queue 有東西就會優先執行。 -
MicroTask Queue 優先層級次高
「Promise」的狀態從 pending 轉變為 resolve 或 reject 時,執行的 callback 會進入這個 Queue。注意:Promise 在創建時是同步的,不會進入 Event Loop。
2.2 用 Node.js 範例程式確認自己是否理解 Event Loop
大家可以先用紙筆模擬看看下面程式的執行順序:
console.log("start");
process.nextTick(function () {
console.log("nextTick1");
});
setTimeout(function () {
console.log("setTimeout");
}, 0);
new Promise(function (resolve, reject) {
console.log("promise");
resolve("resolve");
}).then(function (result) {
console.log(result);
});
(async function () {
console.log("async");
})();
setImmediate(function () {
console.log("setImmediate");
});
process.nextTick(function () {
console.log("nextTick2");
});
console.log("end");
如果答案跟下面結果一樣,那代表你很了解 Node.js 的 Event Loop 邏輯:
start
promise
async
end
nextTick1
nextTick2
resolve
setTimeout
setImmediate
2.3 解析 Node.js 範例程式執行順序
- SETP 1: 順序執行,先把同步函式解決。
-
因為
Promise在創建時是同步的,所以會先執行。 -
在 function 前面加上 async 宣告為異步函式,執行時會被轉換為 Promise。
console.log("start"); new Promise(function (resolve, reject) { console.log("promise"); resolve("resolve"); }).then(function (result) { console.log(result); }); (async function () { console.log("async"); })(); console.log("end");
-
- STEP 2: 進入 Event Loop。
-
如果執行過程中遇到
NextTick Queue就優先執行。process.nextTick(function () { console.log("nextTick1"); }); process.nextTick(function () { console.log("nextTick2"); }); -
在處理完最高優先層級後,如果執行過程中遇到
MicroTask Queue就執行。new Promise(function (resolve, reject) { console.log("promise"); resolve("resolve"); }).then(function (result) { console.log(result); }); -
在前兩個高優先層級的 Queue 清空後,返回 Event Loop 繼續執行,
setTimeout設定的時間已到先執行。setTimeout(function () { console.log("setTimeout"); }, 0); -
接著再在「Check」 階段執行
setImmediatesetImmediate(function () { console.log("setImmediate"); });
-
以上步驟執行完成後就是範例程式的解答啦~希望對大家理解 Event Loop 有幫助。
3. 衍伸問題
3.1 可以簡述 Node.js 跟 JavaScript 的差異嗎?
考點:確認求職者是否理解自己天天使用的工具
JavaScript 是程式語言,可以在合適的瀏覽器中運行;而 Node.js 是一個能執行JavaScript 的環境,它以 Chrome V8 引擎為核心,再加上 C/C++套件,讓 Sever 端也可以執行 JavaScript。
3.2 readFile 和 createReadStream 函式的差異?
考點:判斷求職者過去專案中使否使用過這類函式,並理解差異
readFile 函式會將讀取到的完整內容存在記憶體後傳給使用者,而 createReadStream 函式則是逐塊讀取檔案,不是全部存在記憶體中;因此要讀取較大的檔案時,建議使用 createReadStream ,利用其逐塊讀取的特性能減少使用者等待時間。
3.3 REPL 是什麼?
考點:對專有名詞是否熟悉,能否解釋
REPL(Read Eval Print Loop)是一個用來執行程式語言的虛擬環境。
就像是我們在瀏覽器的 Console 可以執行 JavaScript 程式碼;在安裝完 Node.js 後,新增一個 JavaScript 檔,在終端機輸入node xxx.js便可以執行它。
感謝大家的閱讀,如果喜歡我的文章可以訂閱接收通知;如果有幫助到你,按Like可以讓我更有寫文的動力,我們明天見~
參考資源:
- Node.js 的 Event Loop (事件輪詢)到底在做什麼?(筆者部落格)
- 15 個常見的 Node.js 面試問題及答案
- 你有沒有想過,到底 Server 是如何「同時處理多個 requests」的? - Node.js 篇
在許多人的幫助下,本系列文章已成功出版,除了添加新的篇章,更完善了每個案例的應對進退;如果對現在的職涯感到迷茫,也許這本書能帶給你不一樣的觀點~

留言載入中…