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

继续吗?

相关推荐
new code Boy3 分钟前
escape谨慎使用
前端·javascript·vue.js
叠叠乐21 分钟前
robot_state_publisher 参数
java·前端·算法
Kiri霧21 分钟前
Range循环和切片
前端·后端·学习·golang
小张快跑。30 分钟前
【Java企业级开发】(十一)企业级Web应用程序Servlet框架的使用(上)
java·前端·servlet
小白阿龙40 分钟前
Flex布局子元素无法垂直居中
前端
秋田君1 小时前
前端工程化部署入门:Windows + Nginx 实现多项目独立托管与跨域解决方案
前端·windows·nginx
江城开朗的豌豆1 小时前
阿里邮件下载器使用说明
前端
半兽先生1 小时前
Web 项目地图选型指南:从 Leaflet 到 MapTalks,如何选择合适的地图引擎?
前端
yaoh.wang1 小时前
力扣(LeetCode) 1: 两数之和 - 解法思路
python·程序人生·算法·leetcode·面试·跳槽·哈希算法