当前位置: 首页> 健康> 养生 > 杭州市建设工程招标网_合肥高端网站建设公司_图片外链上传网站_产品市场推广方案

杭州市建设工程招标网_合肥高端网站建设公司_图片外链上传网站_产品市场推广方案

时间:2025/7/13 3:36:23来源:https://blog.csdn.net/2203_75479159/article/details/147283289 浏览次数:0次
杭州市建设工程招标网_合肥高端网站建设公司_图片外链上传网站_产品市场推广方案

浏览器的事件循环机制

文章目录

    • 浏览器的事件循环机制
      • **一、核心概念**
      • **二、事件循环的组成部分**
        • 1. **调用栈(Call Stack)**
        • 2. **Web API**
        • 3. **任务队列(Task Queue)**
        • 4. **事件循环(Event Loop)**
        • 5.**渲染管道(Render Pipeline)**
      • **三、事件循环的完整流程**
      • **四、执行顺序示例**
      • **五、关键规则**
      • **六、实际应用与优化**
        • 1. 避免阻塞主线程
        • 2. 合理使用宏任务和微任务
        • 3. 注意 `requestAnimationFrame`
      • **七、Node.js 与浏览器事件循环的区别**
      • **七、总结**

浏览器的事件循环(Event Loop)是其处理异步任务和维持页面交互的核心机制。由于 JavaScript 是单线程的,事件循环通过协调任务队列、调用栈和 Web API,确保代码高效执行且不阻塞主线程。以下是详细的机制解析:


一、核心概念

  1. 单线程
    JavaScript 只有一个主线程,负责执行脚本、渲染页面等。单线程避免了多线程的复杂性(如死锁),但也导致长时间任务会阻塞页面。
  2. 事件循环的目标
    解决单线程的阻塞问题,通过异步和非阻塞的方式处理耗时操作(如网络请求、定时器)。

二、事件循环的组成部分

1. 调用栈(Call Stack)
  • 记录函数调用的顺序,遵循“后进先出”原则。
  • 当函数执行完毕,从栈顶弹出;遇到异步操作时,将其交给 Web API 处理。
2. Web API
  • 浏览器提供的接口(如 setTimeoutfetch),处理异步任务。
  • 异步任务完成后,回调函数会被推入任务队列。
3. 任务队列(Task Queue)
  • 存放待执行的回调函数,分为两种类型:
    • 宏任务队列(MacroTask Queue):包含 setTimeoutsetInterval、DOM 事件回调等。
    • 微任务队列(MicroTask Queue):包含 Promise.thenMutationObserver 等。
4. 事件循环(Event Loop)
  • 持续检查调用栈是否为空:
    1. 若调用栈为空,优先从微任务队列取出所有任务执行。
    2. 微任务队列清空后,从宏任务队列取出一个任务执行。
    3. 重复上述过程,形成循环。
5.渲染管道(Render Pipeline)
  • 在宏任务和微任务处理后,浏览器决定是否渲染页面。
  • requestAnimationFrame 在渲染前执行。

三、事件循环的完整流程

  1. 执行同步代码
    • 调用栈依次执行同步任务,直至清空。
  2. 处理微任务队列
    • 执行所有微任务(直到队列为空)。
  3. 渲染页面(如有需要)
    • 执行 requestAnimationFrame 回调。
    • 计算布局(Layout)和绘制(Paint)。
  4. 从宏任务队列取一个任务执行
    • setTimeout 回调、事件处理函数。
    • 重复步骤 2-4。

四、执行顺序示例

console.log("Script Start"); // 宏任务1setTimeout(() => {console.log("setTimeout"); // 宏任务2的回调
}, 0);Promise.resolve().then(() => {console.log("Promise 1"); // 微任务1}).then(() => {console.log("Promise 2"); // 微任务2});console.log("Script End"); // 宏任务1继续执行

输出顺序

Script Start → Script End → Promise 1 → Promise 2 → setTimeout

解析

  1. 主线程执行同步代码(宏任务1),遇到 setTimeoutPromise
  2. setTimeout 回调进入宏任务队列,Promise 回调进入微任务队列。
  3. 当前宏任务执行完毕,调用栈为空。
  4. 优先执行所有微任务(Promise 1 → Promise 2)。
  5. 微任务队列清空后,执行下一个宏任务(setTimeout)。

五、关键规则

  1. 微任务优先级高于宏任务
    每次调用栈清空后,必须执行完所有微任务,才会执行下一个宏任务。

  2. 宏任务的类型

    • setTimeout / setInterval
    • I/O 操作(如文件读取)
    • UI 渲染(如 requestAnimationFrame
  3. 微任务的类型

    • Promise.then / catch / finally
    • MutationObserver
    • queueMicrotask()
  4. 微任务嵌套会阻塞渲染

    function loopMicrotasks() {Promise.resolve().then(loopMicrotasks); // 微任务无限递归 → 页面卡死
    }
    loopMicrotasks();
    
  5. 渲染时机

    • 微任务执行后、下一个宏任务前,浏览器可能渲染页面。
    • requestAnimationFrame 用于在渲染前更新动画。

六、实际应用与优化

1. 避免阻塞主线程
  • 将耗时操作(如大量计算)拆分为多个微任务或使用 Web Worker。
2. 合理使用宏任务和微任务
  • 需要尽快执行的逻辑(如状态更新)使用微任务(Promise)。
  • 延迟执行的任务使用宏任务(setTimeout)。
3. 注意 requestAnimationFrame
  • 属于渲染阶段的回调,在浏览器重绘前执行,优先级高于宏任务。

七、Node.js 与浏览器事件循环的区别

特性浏览器Node.js
微任务队列仅一个微任务队列多个阶段(如 timerspollcheck
I/O 处理通过 Web API通过 Libuv 库
事件循环阶段简单分为宏任务和微任务分为多个阶段,每个阶段处理特定任务

七、总结

浏览器的事件循环通过 调用栈Web API任务队列 的协作,实现异步非阻塞的执行模型。理解其机制有助于:

  • 优化代码性能,避免界面卡顿。
  • 正确预测异步代码的执行顺序。
  • 处理复杂的并发场景(如竞态条件)。

事件循环机制
确保异步任务有序执行,避免阻塞主线程。

核心规则
同步代码 → 微任务 → 渲染 → 宏任务 → 循环。

开发注意

  • 避免微任务嵌套过深。
  • 长任务拆分(如用 setTimeout 分片)。
  • 合理使用 requestAnimationFrame 优化动画。

核心口诀
​“宏任务结束,先清微任务;循环往复,永不停歇。”​

关键字:杭州市建设工程招标网_合肥高端网站建设公司_图片外链上传网站_产品市场推广方案

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: