JS 事件循环详解

article/2025/7/5 14:03:58

JS 事件循环详解

文章目录

  • JS 事件循环详解
    • 一、JS 的单线程模型与异步机制
    • 二、事件循环的核心组件
      • 1. 执行栈(Call Stack)
      • 2. 任务队列(Task Queue)
      • 3. Web APIs
    • 三、事件循环的执行流程
    • 四、任务类型详解
      • 1. 宏任务(Macrotask)
      • 2. 微任务(Microtask)
    • 五、经典执行顺序示例
    • 六、实际应用场景
      • 1. 定时任务控制
      • 2. Promise 异步流程
      • 3. DOM 事件优化
    • 七、常见误区与最佳实践
      • 1. 不要阻塞事件循环
      • 2. 微任务嵌套陷阱
      • 3. 合理使用任务优先级

一、JS 的单线程模型与异步机制

JS 是一种单线程语言,这意味着它只有一个主线程(执行栈)来处理所有任务。这种设计避免了多线程环境中的复杂同步问题,但也带来了一个挑战:如何防止长时间运行的代码阻塞整个程序?

解决方案是将代码分为:

  • 同步代码:由 JS 引擎直接执行
  • 异步代码:交给宿主环境(浏览器/Node.js)处理

二、事件循环的核心组件

1. 执行栈(Call Stack)

  • 用于存储同步任务的执行上下文
  • 遵循后进先出(LIFO)原则
  • 当函数执行时会被推入栈顶,执行完毕后弹出

2. 任务队列(Task Queue)

  • 宏任务队列(Macrotask Queue)
  • 微任务队列(Microtask Queue)

3. Web APIs

  • 浏览器提供的异步API(setTimeout、DOM事件等)
  • Node.js 中的 I/O 操作等

三、事件循环的执行流程

  1. 执行同步代码:执行栈中的任务依次执行

  2. 处理微任务

    • 执行栈清空后,立即执行所有微任务
    • 微任务执行期间产生的新微任务会继续执行
  3. 渲染更新(浏览器环境)

  4. 取一个宏任务执行

  5. 重复循环

    在这里插入图片描述

四、任务类型详解

1. 宏任务(Macrotask)

来源示例
setTimeout/setIntervalsetTimeout(fn, 0)
I/O 操作文件读写、网络请求
UI 渲染(浏览器)
事件回调click, scroll
setImmediate(Node.js 特有)

特点:

  • 每次事件循环只执行一个宏任务
  • 优先级低于微任务

2. 微任务(Microtask)

来源示例
Promise.then()/.catch()
MutationObserverDOM 变更观察
process.nextTick(Node.js 特有,优先级最高)

特点:

  • 在当前宏任务结束后立即执行
  • 会清空整个微任务队列
  • 优先级高于宏任务

五、经典执行顺序示例

console.log('1. 同步代码开始');setTimeout(() => {console.log('6. 宏任务1 - setTimeout');Promise.resolve().then(() => {console.log('7. 微任务3 - Promise');});
}, 0);Promise.resolve().then(() => {console.log('3. 微任务1 - Promise');return Promise.resolve();
}).then(() => {console.log('4. 微任务2 - Promise');
});console.log('2. 同步代码结束');// 输出顺序:
// 1. 同步代码开始
// 2. 同步代码结束
// 3. 微任务1 - Promise
// 4. 微任务2 - Promise
// 6. 宏任务1 - setTimeout
// 7. 微任务3 - Promise

六、实际应用场景

1. 定时任务控制

// 动画帧控制
function animate() {// 动画逻辑requestAnimationFrame(animate); // 比setTimeout更适合动画
}
animate();// 轮询检查
function poll() {fetch('/api/status').then(checkStatus).then(() => setTimeout(poll, 5000));
}

2. Promise 异步流程

function loadData() {return fetch('/api/data').then(response => response.json()).then(data => {// 处理数据return processData(data);}).catch(error => {// 错误处理console.error(error);});
}

3. DOM 事件优化

// 防抖处理高频事件
function debounce(fn, delay) {let timer;return function() {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, arguments), delay);};
}window.addEventListener('scroll', debounce(() => {// 处理滚动逻辑
}, 100));

七、常见误区与最佳实践

1. 不要阻塞事件循环

// 错误示范:同步计算阻塞UI
function heavyCalc() {let result = 0;for (let i = 0; i < 1000000000; i++) {result += Math.sqrt(i);}return result;
}// 正确做法:分片处理
async function chunkedHeavyCalc() {let result = 0;for (let i = 0; i < 100000000; i += 100000) {result += await chunkCalc(i, Math.min(i + 100000, 100000000));// 允许浏览器渲染await new Promise(resolve => requestAnimationFrame(resolve));}return result;
}

2. 微任务嵌套陷阱

// 可能导致无限循环
function microtaskLoop() {Promise.resolve().then(microtaskLoop);
}
// microtaskLoop(); // 不要这样做!

3. 合理使用任务优先级

// 需要立即执行的任务使用微任务
function urgentTask(callback) {Promise.resolve().then(callback);
}// 不紧急的任务使用宏任务
function backgroundTask(callback) {setTimeout(callback, 0);
}

http://www.hkcw.cn/article/pDLvRnmODo.shtml

相关文章

堆遇到的stl与理论基础

目录 二叉完全搜索树是堆吗:并不是,堆比两孩子都大 1. 二叉完全搜索树的特点 2. 堆的特点 3. 两者的主要区别 4. 结论 c有swap吗 堆的向上调整和向下调整是什么 1. 堆的定义 2. 向上调整&#xff08;Heapify Up&#xff09; 操作步骤 示例&#xff08;最大堆&#x…

年度工作汇报工作总结PPT模版分享

年度工作汇报工作总结PPT模版分享&#xff1a;工作总结汇报类PPT模版https://pan.quark.cn/s/774660cc70e8

一文学会c++中的内存管理知识点

文章目录 c/c内存管理c语言动态内存管理c动态内存管理new/delete自定义类型妙用operator new和operator delete malloc/new&#xff0c;free/delete区别 c/c内存管理 int globalVar 1;static int staticGlobalVar 1;void Test(){static int staticVar 1;int localVar 1;in…

ZC-OFDM雷达通信一体化减小PAPR——直接限幅法

文章目录 前言一、直接限幅法技术1、简介2、原理 二、MATLAB 仿真1、核心代码2、仿真结果 三、资源自取 前言 在 OFDM 雷达通信一体化系统中&#xff0c;信号的传输由多个子载波协同完成&#xff0c;多个载波信号相互叠加形成最终的发射信号。此叠加过程可能导致信号峰值显著高…

【二维数组】

二维数组 需要掌握的知识二维数组与内存二维数组语法Arrays类的常用方法介绍如何实现冒泡排序 需要掌握的知识 二维数组与内存 二维数组语法 //数据类型【】【】数组; //或者 //数据类型 数组名【】【】&#xff1b; //二维数组初始化操作 int [][] scorenew int[][]{{90,85,92…

小黑大语言模型通过设计demo进行应用探索:langchain中chain的简单理解demo

chain简介 LangChain 中的 Chain 模块‌在开发大型语言模型&#xff08;LLM&#xff09;驱动的应用程序中起着至关重要的作用。Chain是串联LLM能力与实际业务的关键桥梁&#xff0c;通过将多个工具和模块按逻辑串联起来&#xff0c;实现复杂任务的多步骤流程编排。 案例 通过…

职坐标精选嵌入式AI物联网开源项目

随着嵌入式、AI与物联网技术的深度融合&#xff0c;开源生态已成为开发者构建智能硬件解决方案的核心驱动力。本文将从嵌入式实时操作系统、多模态AI数据集及物联网接入平台三大维度切入&#xff0c;系统性梳理技术选型要点与实践路径。在嵌入式领域&#xff0c;重点解析低功耗…

闻晓医考---口腔执业医师483分的复习攻略

&#x1f308;分清考试主次 &#x1f386;核心: 口外(114分) 口修(112分) 牙体牙髓(72分) &#x1f386;重点: 口预(50分) 临床医学(49分) 口组病(33分) 口解(33分) 牙周(30分) &#x1f386;次重点: 儿口(16分) 口腔黏膜(16分) 免疫&#xff08;8分&#xff09;…

火语言UI组件--幻灯片

【组件功能】&#xff1a;在有限空间内&#xff0c;循环播放同一类型的图片、文字等内容。 样式预览 基础设置 属性名称属性释义输入值类型初始索引(initialIndex)设置初始状态激活的幻灯片的索引&#xff0c;从 0 开始数字型(Number)触发方式(trigger)设置指示器的触发方式(…

矿用电液控连接器LCFB-12钢丝编织橡胶护套连接器

矿用电液控连接器LCFB-12钢丝编织橡胶护套连接器是煤矿井下综采工作面液压支架电液控制系统中的关键部件,其性能直接关系到整个液压系统的稳定性和安全性。随着智能化采矿技术的快速发展,这类连接器的技术要求和应用场景也在不断升级。本文将从产品结构、技术特点、行业应用及…

基于CAPL的DDS子消息解析- Data

1往期回顾 通过《DDS—RTPS一致性测试案例分析》一文&#xff0c;我们了解到 Data 子消息在 Data Distribution Service(DDS) 通信中扮演着至关重要的角色。它不仅负责 DDS 实体的 Simple Participant Discovery Protocol (SPDP) 发现流程&#xff0c;还参与了 Simple Endpoin…

MySQL之数据库的内嵌函数和联合查询

MySQL之数据库的内嵌函数和联合查询 一.数据库的内嵌函数1.1聚合函数1.2日期函数1.3字符串处理函数1.4 数学函数1.5其他常用的函数 二.联合查询2.1笛卡尔积2.2内连接2.3外连接2.4 自连接2.5子查询2.6合并查询 一.数据库的内嵌函数 1.1聚合函数 在MySQL中有着一类聚合函数来方…

【AUTOSAR OS】内存保护模块技术解析

一、模块总体功能概述 Os_Mprot.c 是AUTOSAR Classic Platform(CP)中内存保护模块的核心实现,主要负责验证任务(Task)和中断服务程序(ISR)对内存区域的访问权限,确保系统资源的合法使用。其核心功能包括: 内存访问权限校验:根据任务/中断所属的应用(App)信任级别(…

Docker 跨平台支持:从 Linux 到 macOS 的容器化开发实践

Docker 容器的理念是“一次构建,处处运行”,旨在解决应用程序在不同环境中部署的兼容性问题。然而,这一承诺的实现,在非原生 Linux 系统(如 macOS 和 Windows)上,需要巧妙的底层机制来支撑。 对于开发者而言,理解 Docker Desktop 在这些操作系统上的工作原理,特别是其…

电机试验平台:现代科技与工程应用的典范

电机试验平台作为电机行业中至关重要的一环&#xff0c;扮演着起着举足轻重的角色。随着科技的进步和工程技术的不断发展&#xff0c;电机试验平台也在不断创新和完善。本文将从电机试验平台的基本概念、发展历程、技术特点以及未来趋势等方面展开介绍。通过深入探讨&#xff0…

[paddle]paddle2onnx无法转换Paddle3.0.0的json格式paddle inference模型

使用PDX 3.0rc1 训练时序缺陷检测后导出的模型无法转换 Informations (please complete the following information): Inference engine for deployment: PD INFERENCE 3.0-->onnxruntime Why convert to onnx&#xff1a;在端侧设备上部署 Paddle2ONNX Version: 1.3.1 解…

内核进程基础

进程定义 操作系统作为硬件的使用层&#xff0c;提供使用硬件资源的能力&#xff1b;进程作为操作系统的使用层&#xff0c;提供使用操作系统抽象出的资源层的能力。 进程&#xff1a;是指计算机中已运行的程序。进程本身不是基本的运行单位&#xff0c;而是线程的容器。程序…

nic_monitor-全面监控以太网、IB、RoCE网络流量的工具

本文提供三个工具,1. nic_monitor 使用脚本语言 Bash Shell 编写的,用来监控以太网或者RDMA接口流量使用的。 2. nic_monitor_v2.0_eth.py 通过TUI界面实时显示以太网流量的工具,使用Python3编写的。3. nic_monitor_v2.1_rdma.py 通过TUI界面实时显示 IB 和 RoCE 流量的工具…

【论文解读】CVPR2023 PoseFormerV2:3D人体姿态估计(附论文地址)

论文链接&#xff1a;https://arxiv.org/pdf/2303.17472 源码链接&#xff1a;https://github.com/QitaoZhao/PoseFormerV2 Abstract 本文提出了 PoseFormerV2&#xff0c;通过探索频率域来提高 3D 人体姿态估计的效率和鲁棒性。PoseFormerV2 利用离散余弦变换&#xff08;DC…

01流程定位

1.以客户为中心&#xff0c;端到端创造价值 大家要思考一个核心问题&#xff0c;企业用什么为客户创造价值&#xff1f; 流程管理大师-迈克而哈默博士回答&#xff0c;不是产品和服务&#xff0c;而是业务流程&#xff0c;是创造、交付产品和服务背后的各种业务流程&#xff0…