好的,继续 第 31 题(超级高频,全栈必考) 。
第 31 题:浏览器与 Node.js 的事件循环有什么区别?
这题是事件循环最容易被问"细节"的地方。
前端工程师面试:80% 会问
Node 面试:100% 会问
一、为什么有事件循环?(必会)
因为 JS 是单线程 → 不能阻塞 → 异步任务需要排队执行
事件循环就是管理 同步任务 + 异步任务(宏任务、微任务) 的调度器。
二、浏览器事件循环流程(记住一句话)
微任务永远在下一轮宏任务前执行。
任务分类:
宏任务(Macro Task)
- setTimeout
- setInterval
- DOM 事件
- I/O
- script 整体代码
- MessageChannel
- postMessage
微任务(Micro Task)
- Promise.then / catch / finally
- MutationObserver
- queueMicrotask
浏览器事件循环步骤(最重要的三步)
1. 执行一个宏任务(script)
2. 清空全部微任务队列
3. UI 渲染(可能发生)
然后继续下一轮循环。
浏览器口诀(面试好用)
一次宏任务 → 清空全部微任务 → 再下一轮宏任务
三、Node.js 事件循环(关键点:6 个阶段 + 微任务在每个阶段之间执行)
Node.js 基于 libuv,事件循环有 6 个阶段:
-
timers 阶段
- 执行 setTimeout / setInterval 的回调
-
pending callbacks 阶段
- 执行某些系统级回调
-
idle / prepare 阶段
- libuv 内部使用(面试不问)
-
poll 阶段(最重要)
- 处理 I/O 回调
- 如果队列为空,会阻塞等待
- 若有 setImmediate,则跳到 check
-
check 阶段
- 执行 setImmediate 回调
-
close callbacks 阶段
- 执行 close 事件,如
socket.on('close')
- 执行 close 事件,如
⚠ Node 微任务的执行规则(区别核心)
Node 会在每个阶段之间都执行微任务队列(nextTick > Promise)。
微任务优先级(Node 专属):
- process.nextTick(最高优先级!)
- Promise.then(普通微任务)
四、浏览器 vs Node.js 事件循环区别(面试官喜欢问)
| 比较点 | 浏览器 | Node.js |
|---|---|---|
| 微任务执行时机 | 每轮宏任务后 统一清空 | 每个阶段之间都执行 |
| 微任务优先级 | Promise 优先 | nextTick > Promise |
| 定时器与 IO | 无阶段 | 有 6 个阶段 |
| setTimeout vs setImmediate | setTimeout ≈ 下轮宏任务 | setImmediate 在 check 阶段(更快) |
| 渲染机制 | 微任务清空后可能渲染 UI | 没有 UI 渲染 |
五、必考例题(一定会考,就考这个!)
例题 1(浏览器):
javascript
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
console.log(4);
执行顺序:
1
4
3 ← 微任务优先
2
例题 2(Node.js):
javascript
setTimeout(() => {
console.log('timeout');
});
setImmediate(() => {
console.log('immediate');
});
Node 常见情况:
bash
timeout
immediate
但实际不一定稳定,同一次 I/O 后执行:
bash
immediate
timeout
例题 3(Node 微任务优先级)
javascript
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
输出:
arduino
nextTick
promise
六、20 秒背诵版(面试必杀技)
浏览器:一次宏任务执行后,会立即清空所有微任务,然后再进行下一轮宏任务;微任务包括 Promise 和 queueMicrotask。
Node:基于 libuv,有 6 个阶段,每个阶段之间都会执行微任务;且微任务优先级是 nextTick > Promise。浏览器只有宏任务 → 微任务
Node 每个阶段之间都插一次微任务。
要继续 第 32 题:Promise 实现原理(手写) 吗?