[面试][後端]请简述 Node.js 的 Event Loop

熟悉的起手式:「我方便问你一个 Node.js 核心的问题吗?」

这是一个在了解後,无论面试还是工作,CP 值都很高的题目,建议读者要真的融会贯通。

大纲

  1. 请简述 Node.js 的 Event Loop

    • 1.1 面试官为什麽会问?
    • 1.2 面试官想从答案确认什麽?
    • 1.3 笔者提供的简答
  2. 回答问题所需具备的知识

    • 2.1 Event Loop 执行的逻辑
    • 2.2 用 Node.js 范例程序确认自己是否理解 Event Loop
    • 2.3 解析 Node.js 范例程序执行顺序
  3. 衍伸问题

    • 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 执行的逻辑

https://ithelp.ithome.com.tw/upload/images/20210919/20103256BPTVtHaRmr.png

  • 了解 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。

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: 顺序执行,先把同步函式解决。

    1. 因为 Promise 在创建时是同步的,所以会先执行。

    2. 在 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。

    1. 如果执行过程中遇到 NextTick Queue 就优先执行。

      process.nextTick(function () {
        console.log("nextTick1");
      });
      
      process.nextTick(function () {
        console.log("nextTick2");
      });
      
    2. 在处理完最高优先层级後,如果执行过程中遇到 MicroTask Queue 就执行。

      new Promise(function (resolve, reject) {
        console.log("promise");
        resolve("resolve");
      }).then(function (result) {
        console.log(result);
      });
      
    3. 在前两个高优先层级的 Queue 清空後,返回 Event Loop 继续执行,setTimeout 设定的时间已到先执行。

      setTimeout(function () {
        console.log("setTimeout");
      }, 0);
      
    4. 接着再在「Check」 阶段执行 setImmediate

      setImmediate(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可以让我更有写文的动力,我们明天见~

参考资源:

  1. Node.js 的 Event Loop (事件轮询)到底在做什麽?(笔者部落格)
  2. 15 个常见的 Node.js 面试问题及答案
  3. 你有没有想过,到底 Server 是如何「同时处理多个 requests」的? - Node.js 篇

我在 Medium 平台 也分享了许多技术文章
❝ 主题涵盖「MIS & DEVOPS资料库前端後端MICROSFT 365GOOGLE 云端应用自我修炼」希望可以帮助遇到相同问题、想自我成长的人。❞


<<:  Day21 Open-Match 端点暴露

>>:  [Angular] Day29. Internationalization (i18n)

Day 19 ml5.js 将 tensorflow 模型转换为 ml5 模型

我们可以将电脑的上 tensorflow 模型转换为 ml5 模型,并在浏览器上执行。 这代表我们可...

Day 04 Introduction to AI

Understand responsible AI Fairness - Without incor...

Day 19 - UML x Component — Independent (上)

前面把有依赖关系的 Component 都讲一讲之後,今天就来带过其他的 UI 元件吧,因为想介绍...

Day 4 - 用 canvas 复刻 小画家 填入色彩, 橡皮擦

填满色彩 在点击画布时,使用 fillStyle 先填上颜色,再覆盖整个画布 /** * 滑鼠点下画...

Day 26 : Github Actions

什麽是Github Actions呢?这是Github平台 在2019年上架的CI功能,使用Gith...