【前端】JavaScript 的事件循环 (Event Loop)

JavaScript 的事件循环 (Event Loop ) 是其实现异步编程的核心机制,即使 JS 是单线程语言,它也能高效处理 I/O、网络请求、计时器等非阻塞操作。以下是其工作原理的精要解析:


核心概念

  1. 单线程执行

    • JS 引擎(如 V8)只能顺序执行一个任务。
    • 异步行为需要靠宿主环境(浏览器/Node.js)提供的事件循环调度。
  2. 任务队列 (Task Queue)

    • 所有异步操作完成后对应的回调函数会进入队列等待执行。
    • 队列类型包括:
      • 宏任务队列 (Macrotask Queue)script(整体代码)、setTimeoutsetInterval、DOM 事件回调、I/O 操作。
      • 微任务队列 (Microtask Queue)Promise.then()await后续代码、MutationObserverqueueMicrotask()

事件循环执行流程

  1. 执行同步代码

    运行主线程的同步任务,形成执行栈(Call Stack),若遇到异步操作(如 setTimeoutfetch),交给 Web API 处理。

  2. 异步任务回调入队

    异步操作完成后,Web API 将其回调推入对应队列:

    • 宏任务回调 → 宏任务队列
    • 微任务回调 → 微任务队列
  3. 轮询事件队列(关键步骤)

    • 执行完当前所有同步任务 后,按优先级处理队列:
      1. 清空微任务队列
        将所有可执行的微任务按顺序执行直至队列为空(执行中可能产生新微任务)。
      2. 执行一个宏任务
        从宏任务队列中取出最早的一个任务执行。
      3. 再次清空微任务队列
        执行该宏任务过程中产生的所有微任务。
      4. 更新渲染(浏览器环境下)
        如有需要,执行 UI 渲染、布局计算等。
    • 循环:重复步骤 3,直至所有队列为空。

执行顺序示例代码解析

javascript 复制代码
console.log("1. 同步代码开始");

setTimeout(() => {
  console.log("4. 宏任务 (setTimeout)");
}, 0);

Promise.resolve().then(() => {
  console.log("3. 微任务 (Promise)");
});

console.log("2. 同步代码结束");

输出顺序
1. 同步代码开始2. 同步代码结束3. 微任务 (Promise)4. 宏任务 (setTimeout)

原因

  • 先执行完所有同步代码(输出 1 和 2)。
  • 微任务队列优先于宏任务队列执行(Promise.then()setTimeout 前)。

为什么区分宏任务与微任务?

  • 微任务的优先级更高
    确保诸如 Promise 状态更新后能立即触发回调,提升用户体验(如快速响应用户操作)。
  • 避免渲染阻塞
    浏览器在宏任务之间插入 UI 渲染流程,而微任务在渲染前全部执行,保证页面及时更新。

事件循环流程图

复制代码
     同步代码执行
         ↓
  遇到异步操作 → Web API 处理 → 完成后回调入队
         ↓                      ↗ 宏任务队列
         |                     /
事件循环开始                 ↓
         |          下一轮循环  取出最早宏任务 → 执行
         |              ↑          ↓
         |------→ 清空微任务队列 → 可能产生新微任务
                       |
                   (浏览器环境下)
                        ↓
                    需要渲染? → 执行渲染流程

⚠️ 常见误区

  1. setTimeout(0) 并非立即执行
    定时器时间仅表示最小延迟,实际回调需等待同步任务及队列中的任务完成。
  2. 微任务会阻塞页面渲染
    长时间的微任务链会导致 UI 冻结。
  3. Node.js 与浏览器的事件循环差异
    Node.js 的事件循环分为更多阶段(如 nextTick 优先级最高)。

掌握事件循环机制,能帮你精准控制代码时序、避免竞态条件,并理解框架如 Vue/React 的底层调度原理!

相关推荐
snowbitx6 分钟前
Vue开发尝试一下
前端
前端缘梦10 分钟前
JavaScript 高频面试题精讲:var、let、const 与类型系统全解析
前端·面试
阿慧勇闯大前端10 分钟前
TypeScript 从入门到放弃any:老大说再写 any 就扣钱!
前端
AI悦创Python辅导11 分钟前
路径分析到底怎么玩?一文搞懂!
前端
mrsk12 分钟前
用魔塔来体验一把NLP(机械学习)
前端·机器学习·面试
袋鱼不重12 分钟前
Vue3 Effect源码解析
前端·javascript·vue.js
福娃B12 分钟前
【React】React 状态管理与组件通信:Zustand vs Redux📦
前端·react.js·前端框架
硅基宙宇AIGC14 分钟前
亲测鹅厂Codebuddy!抢到多个邀请码后发现了AI编程的天花板?(文末送码)
前端·后端
南屿im15 分钟前
从零实现字符串模板引擎:从 正则解析 到 AST 思路解析 的进阶之路
前端·javascript
无羡仙15 分钟前
React 路由配置:useRoutes 的使用详解
前端·javascript