前端事件循环

前端事件循环(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

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

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

执行优先级

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

微任务的嵌套执行

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

相关推荐
WeiXiao_Hyy14 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡31 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone37 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
Serene_Dream1 小时前
JVM 并发 GC - 三色标记
jvm·面试
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库