第 32 题:深入理解事件循环(Event Loop)、微任务、宏任务(详细 + 难点 + 易错点)

好的,继续你的前端高频题训练。


第 37 题:深入理解事件循环(Event Loop)、微任务、宏任务(详细 + 难点 + 易错点)

这题在前端面试中属于 顶级高频题,并且往往是笔试 + 面试双重考。

我会讲:

  • 原理(你能向面试官讲清楚的那种)
  • 浏览器与 Node 的区别
  • 经典必考输出题
  • 容易被坑的知识点
  • 速记卡片

一、什么是事件循环(Event Loop)?

一句话:

JS 是单线程的,为了不阻塞任务执行,就通过事件循环机制来调度异步任务。

事件循环主要处理两类任务:

  • 宏任务(Macro task)
  • 微任务(Micro task)

二、宏任务 vs 微任务(非常关键)

✔ 宏任务(Macro task)

每一轮事件循环执行 一个 宏任务。

常见宏任务:

  • setTimeout
  • setInterval
  • setImmediate(Node)
  • I/O
  • UI 渲染
  • 整个 script 一次整体执行(没错,script 也是宏任务)

✔ 微任务(Micro task)

当一个宏任务执行结束后,会立即清空所有微任务队列。

常见微任务:

  • Promise.then / catch / finally
  • MutationObserver
  • queueMicrotask
  • Node 中还有 process.nextTick(优先级最高)

三、事件循环执行顺序(面试官最爱问)

一句话版流程:

复制代码
执行宏任务
  ↓
执行期间遇到微任务 → 放入微任务队列
  ↓
当前宏任务执行完 → 立即清空所有微任务
  ↓
进入下一轮宏任务

四、浏览器 vs Node 的区别(高频点)

浏览器事件循环:

复制代码
宏任务 → 微任务 → 渲染 → 下一轮宏任务

Node 事件循环更复杂,有六个阶段:

  1. timers
  2. pending callbacks
  3. idle, prepare
  4. poll
  5. check
  6. close callbacks

以及:

  • process.nextTick(优先级最高)
  • 然后才是微任务(Promise)

五、经典必考题(你必须会默写)


📌 例题 1:Promise vs setTimeout

javascript 复制代码
console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

console.log(4);

执行顺序:

1 → 4 → 3 → 2

解析:

  • 1、4:同步
  • 3:微任务
  • 2:宏任务

📌 例题 2:嵌套微任务

javascript 复制代码
Promise.resolve().then(() => {
  console.log('micro 1');
  Promise.resolve().then(() => console.log('micro 2'));
});

console.log('sync');

输出:

bash 复制代码
sync
micro 1
micro 2

原因:

微任务永远全部清空。


📌 例题 3:setTimeout vs Promise 再套 setTimeout

javascript 复制代码
setTimeout(() => console.log(1));

Promise.resolve().then(() => {
  console.log(2);
  setTimeout(() => console.log(3));
});

console.log(4);

顺序:

4 → 2 → 1 → 3

解释:

  • 4:同步
  • 2:微任务
  • 1:第一轮的宏任务
  • 3:Promise 里的 setTimeout → 第二轮宏任务

📌 例题 4:Node 特性 --- process.nextTick

javascript 复制代码
console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

process.nextTick(() => console.log(4));

console.log(5);

Node 输出:

arduino 复制代码
1
5
4   ← process.nextTick 优先级最高
3   ← 微任务
2   ← 宏任务

六、面试官深入追问(你必须会答)


❓为什么 Promise.then 会比 setTimeout 先执行?

因为 Promise 是微任务,而 setTimeout 是宏任务。

每一轮事件循环结束会立即执行所有微任务 → 永远先于宏任务。


❓微任务可以产生新的微任务吗?

可以,而且会继续在当前 microtask queue 中执行。


❓浏览器什么时候渲染?

一次事件循环中:

复制代码
宏任务 → 微任务 → (若需要则渲染)

渲染只在两次宏任务之间,不会打断微任务执行。


七、速记卡片(给你复习)


🟦 事件循环 --- 速记卡片

🟣 宏任务(一次执行一个)

  • script
  • setTimeout
  • setInterval
  • UI 渲染
  • I/O

🔵 微任务(每轮执行完宏任务就清空)

  • Promise.then
  • queueMicrotask
  • MutationObserver
  • (Node) process.nextTick(优先级最高)

🟢 执行顺序

复制代码
宏任务
→ 执行所有微任务
→ 渲染(浏览器)
→ 下一轮宏任务

🔴 Node 特殊优先级

arduino 复制代码
process.nextTick > Promise microtask > macrotask

要继续第 38 题吗?

下一题是:

👉 第 38 题:浏览器渲染流程(重排 Reflow、重绘 Repaint、合成 Compositing)

继续吗?

相关推荐
何陋轩20 分钟前
OpenAI Codex深度解析:终端里的AI代码特工,一个指令重构整个项目
人工智能·面试
沃尔威武24 分钟前
调试黑科技:Chrome DevTools时间旅行调试实战
前端·科技·chrome devtools
yuki_uix32 分钟前
虚拟 DOM 与 Diff 算法——React 性能优化的底层逻辑
前端·react.js·面试
yuki_uix33 分钟前
从输入 URL 到页面显示——浏览器工作原理全解析
前端·面试
weixin_408099671 小时前
【完整教程】天诺脚本如何调用 OCR 文字识别 API?自动识别屏幕文字实战(附代码)
前端·人工智能·后端·ocr·api·天诺脚本·自动识别文字脚本
吴声子夜歌1 小时前
ES6——Generator函数详解
前端·javascript·es6
吴声子夜歌1 小时前
ES6——Set和Map详解
前端·javascript·es6
码喽7号1 小时前
vue学习四:Axios网络请求
前端·vue.js·学习
粥里有勺糖2 小时前
视野修炼-技术周刊第129期 | 上一次古法编程是什么时候
前端·javascript·github
whuhewei2 小时前
JS获取CSS动画的旋转角度
前端·javascript·css