面试第一关!面试官:讲一下事件循环机制,宏&微任务,还有渲染时机

JavaScript 是单线程、非阻塞、异步 的语言,事件循环(Event Loop)就是 JS 引擎用来管理异步任务执行顺序的核心机制。

它决定了代码什么时候运行、异步任务如何排队、页面什么时候渲染,是理解 JS 异步编程的基础。

宏任务 和 微任务

事件循环把异步任务分为宏任务(Macrotask)微任务(Microtask)

执行优先级:

同步代码 > 微任务 > 宏任务

宏任务(Macrotask)

每次事件循环只执行一个,执行完就去检查微任务队列。

比较常见的宏任务是:

script 整体代码、setTimeout/setInterval、AJAX/fetch 网络请求、I/O 操作、UI 渲染、postMessageMessageChannel

遵循先进先出(FIFO)的队列机制。

2. 微任务(Microtask)

微任务优先级高于宏任务 ,每次宏任务执行完,会清空当前所有微任务后,再进入下一个循环。

常见的微任务:

Promise.then/catch/finallyasync/await(底层就是 Promise)、queueMicrotask()MutationObserver

其队列机制是一次性清空全部微任务,再执行后续逻辑。

标准执行流程

  1. 执行同步代码(主线程执行栈);
  2. 同步执行完,立即清空所有微任务(微任务队列全部执行);
  3. 微任务清空后,检查是否需要 UI 渲染(浏览器渲染线程工作);
  4. 渲染完成后,取出一个宏任务执行
  5. 重复以上循环。

一句话口诀:同步 → 微任务 → 渲染 → 宏任务(循环)

浏览器渲染时机

1. 渲染触发时机
  • 在微任务清空之后、下一个宏任务之前执行;

  • 不是每次事件循环都一定渲染,浏览器有渲染帧率限制(约 16ms 一次,60fps),会合并多次 DOM 修改做一次渲染,避免频繁重绘重排。

2. 关键结论
  1. 微任务会阻塞渲染:微任务没执行完,页面绝对不会渲染;
  2. DOM 修改在微任务后统一更新:在微任务里修改 DOM,会在本次循环渲染阶段统一生效;
  3. 宏任务在渲染之后执行setTimeout 等宏任务,一定在页面渲染完成后才运行。

场景示例代码:

js 复制代码
// 执行顺序:同步 → 微任务(Promise) → 渲染 → 宏任务(setTimeout)
console.log('同步1');
Promise.resolve().then(() => {
  console.log('微任务');
  document.body.style.background = 'red'; // DOM修改,渲染时生效
});
console.log('同步2');
setTimeout(() => {
  console.log('宏任务'); // 最后执行
}, 0);

补充内容

  1. Node.js 与浏览器事件循环差异
  • 浏览器:只有一个宏任务队列;
  • Node:分为 timers、pending callbacks 等六个阶段,微任务在每个阶段切换时清空(Node 15+ 已对齐浏览器规范)。
  1. async/await 本质
  • 就是 Promise 语法糖,await 后面的代码属于微任务,优先级高于定时器、网络请求。
  1. 性能影响
  • 微任务过多会阻塞渲染,导致页面卡顿;避免在微任务中执行大量耗时逻辑。
  1. 渲染线程互斥
  • JS 执行与 DOM 渲染共用同一个线程,微任务阻塞 → 渲染阻塞 → 页面卡顿。

1分钟面试简洁版

事件循环是 JS 单线程下管理异步任务的核心机制,核心是宏任务、微任务、渲染时机三者的执行顺序。

首先,JS 先执行同步代码,执行完后先清空所有微任务 ,比如 Promise、async/await;微任务全部执行完之后,浏览器才会执行UI 渲染

渲染完成后,再取下一个宏任务执行,比如 setTimeout、网络请求,循环往复。

简单说顺序就是:同步代码 → 微任务 → 渲染 → 宏任务

微任务优先级高于宏任务,而且会阻塞渲染,必须等微任务全部执行完,页面才会更新。宏任务一定在渲染之后执行。

日常开发中,需要优先用微任务处理实时逻辑,避免大量微任务阻塞页面渲染。

相关推荐
linweidong1 小时前
iOS 开发面试 50 个高频易混淆知识点详解
ios·设计模式·面试·cocoa·uikit·uiview·uistackview
shuoshuohaohao1 小时前
《CSS》
前端·css
西部荒野子1 小时前
Zustand 状态管理规范:别让轻量状态变成隐形通知风暴
前端·javascript
之歆1 小时前
Day03_ES6 深度解析与实战应用:运算符、Symbol、Class、集合与迭代协议
前端·ecmascript·es6
Carson带你学Android1 小时前
Kotlin放大招!官方 Skills 直接喂出「专家级」代码
android·前端·kotlin
之歆1 小时前
Day04_ES6完全指南:从入门到精通的现代化JavaScript开发
前端·javascript·es6
Coffeeee1 小时前
一个kotlin的Smart cast导致的编译问题
android·前端·kotlin
CodeSheep2 小时前
胡彦斌都开始苦修Vibe Coding,还上架App Store,都卷到编程来了吗?
前端·后端·程序员