第 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)

继续吗?

相关推荐
徐小夕25 分钟前
JitWord Office预览引擎:如何用Vue3+Node.js打造丝滑的PDF/Excel/PPT嵌入方案
前端·vue.js·github
晴殇i34 分钟前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
孟陬1 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
BER_c1 小时前
前端权限校验最佳实践:一个健壮的柯里化工具函数
前端·javascript
兆子龙1 小时前
别再用 useState / data 管 Tabs 的 activeKey 了:和 URL 绑定才香
前端·架构
sudo_jin1 小时前
前端包管理器演进史:为什么 npm 之后,Yarn 和 pnpm 成了新宠?
前端·npm
绝无仅有1 小时前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有1 小时前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
叁两2 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
golang学习记2 小时前
GitLens 十大神技:彻底改变你在 VS Code 中的 Git 工作流
前端·后端·visual studio code