前端事件循环

前端事件循环(Event Loop)是 JavaScript 运行时处理异步任务的核心机制,它决定了代码执行的顺序和优先级,使 JavaScript 在单线程环境中高效处理异步任务,确保用户界面的流畅性和响应性。

单线程与异步执行的矛盾

JavaScript 在浏览器环境中是单线程运行的,这意味着它同一时间只能执行一个任务。例如,当执行一段复杂的计算任务时,其他任务(如用户点击事件、页面渲染)都必须等待该计算完成。这种特性在处理需要大量时间的任务时,可能会导致页面卡顿,影响用户体验。然而,前端开发中存在许多耗时操作,如网络请求(fetch)、定时器(setTimeoutsetInterval)等。如果这些操作都以同步方式执行,整个页面将会冻结,直到操作完成。为了解决这个矛盾,JavaScript 引入了事件循环机制,它允许在执行同步任务的同时,异步处理其他任务。

工作原理

调用栈

同步代码逐行执行(后进先出,LIFO)

函数调用时入栈,执行完毕出栈

任务队列

宏任务队列(MacroTask Queue)setTimeoutsetInterval、DOM 事件回调、I/O 操作

微任务队列(MicroTask Queue)Promise.thenMutationObserverqueueMicrotask

渲染管线(Render Pipeline) :样式计算、布局、绘制(requestAnimationFrame 回调在此阶段执行)

事件循环流程

markdown 复制代码
while (true) {
  1. 执行调用栈中的同步代码(直到栈空)
  2. 执行所有微任务(清空微任务队列)
  3. 渲染页面(如果需要)
  4. 取一个宏任务执行
}

事件循环不断检查调用栈是否为空。当调用栈为空时,事件循环从任务队列中取出一个任务(回调函数),将其压入调用栈执行。如此循环往复,实现异步任务的有序执行。

示例

javascript 复制代码
console.log('1'); // 同步代码

setTimeout(() => {
  console.log('2'); // 宏任务
  Promise.resolve().then(() => console.log('3')); // 微任务
}, 0);

Promise.resolve().then(() => {
  console.log('4'); // 微任务
  setTimeout(() => console.log('5'), 0); // 宏任务
});

// 输出顺序:1 → 4 → 2 → 3 → 5

事件循环每次从宏任务队列中取出一个宏任务执行。在执行宏任务过程中,可能会产生新的宏任务或微任务。

在当前宏任务执行完毕后,事件循环会立即处理微任务队列中的所有微任务,直到微任务队列为空,才会去取下一个宏任务。

执行优先级

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

微任务的嵌套执行

微任务队列必须完全清空后,才会执行下一个宏任务或渲染

相关推荐
落霞的思绪14 分钟前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q16 分钟前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz24 分钟前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
橙露1 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
Exquisite.1 小时前
Nginx
服务器·前端·nginx
2501_920931701 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...1 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov1 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发
打小就很皮...1 小时前
React 19 + Vite 6 + SWC 构建优化实践
前端·react.js·vite·swc
Highcharts.js2 小时前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档