js中的微任务和宏任务的理解

在JavaScript中,微任务(Microtask)和宏任务(Macrotask)是异步任务执行机制的重要组成部分,它们共同构成了JavaScript事件循环(Event Loop)的核心逻辑。理解这两个概念对于编写高性能、无阻塞的代码至关重要。

1. 基本概念

宏任务(Macrotask)
  • 定义:由浏览器或Node.js环境提供的异步任务,通常是一些离散的、独立的操作。
  • 常见宏任务
    • setTimeoutsetInterval
    • setImmediate(Node.js)
    • requestAnimationFrame(浏览器)
    • I/O操作(如文件读取、网络请求)
    • UI渲染(浏览器)
微任务(Microtask)
  • 定义:JavaScript引擎自身提供的异步任务,通常是需要在当前任务完成后立即执行的操作。
  • 常见微任务
    • Promise.then()Promise.catch()Promise.finally()
    • MutationObserver(浏览器)
    • process.nextTick(Node.js)
    • queueMicrotask(ES2020+)

2. 执行顺序规则

JavaScript的事件循环执行机制遵循以下规则:

  1. 执行栈(Call Stack) 为空时,事件循环开始处理任务队列。
  2. 宏任务队列 每次只取一个任务执行,执行完毕后立即处理 微任务队列
  3. 微任务队列 会被清空(依次执行所有微任务),直到队列为空。
  4. 微任务队列清空后:
    • 浏览器可能进行 UI渲染(仅在浏览器环境)。
    • 事件循环回到步骤2,继续处理下一个宏任务。

总结宏任务 → 清空微任务队列 → UI渲染 → 下一个宏任务

3. 经典示例分析

console.log('1. 主线程开始');// 宏任务1
setTimeout(() => {console.log('2. setTimeout 回调执行');// 微任务1Promise.resolve().then(() => {console.log('3. setTimeout 内部 Promise 微任务执行');});
}, 0);// 微任务2
Promise.resolve().then(() => {console.log('4. 主线程 Promise 微任务执行');// 微任务3queueMicrotask(() => {console.log('5. queueMicrotask 微任务执行');});
});console.log('6. 主线程结束');

执行顺序解析

  1. 主线程 执行:

    • 输出 1. 主线程开始
    • setTimeout 被放入 宏任务队列
    • Promise.then 被放入 微任务队列(微任务2)。
    • 输出 6. 主线程结束
  2. 微任务队列 执行:

    • 执行微任务2,输出 4. 主线程 Promise 微任务执行
    • queueMicrotask 被加入微任务队列(微任务3)。
    • 继续执行微任务3,输出 5. queueMicrotask 微任务执行
  3. 宏任务队列 执行:

    • 执行宏任务1(setTimeout 回调),输出 2. setTimeout 回调执行
    • Promise.then 被加入微任务队列(微任务1)。
    • 清空微任务队列,执行微任务1,输出 3. setTimeout 内部 Promise 微任务执行

最终输出顺序

1. 主线程开始
6. 主线程结束
4. 主线程 Promise 微任务执行
5. queueMicrotask 微任务执行
2. setTimeout 回调执行
3. setTimeout 内部 Promise 微任务执行

4. 实际应用场景

4.1 微任务的应用
  • Promise链式调用:确保回调按顺序执行,不阻塞主线程。
    fetchData().then(processData).then(updateUI).catch(handleError);
    
  • DOM变更后立即操作:使用 MutationObserver 监听DOM变化后执行回调。
4.2 宏任务的应用
  • 定时器:实现延迟执行或周期性任务。
    setTimeout(() => {// 延迟执行的代码
    }, 1000);
    
  • 分批处理大量数据:避免长时间阻塞主线程。
    function processLargeData(data) {const batchSize = 1000;let index = 0;function processBatch() {const batch = data.slice(index, index + batchSize);// 处理当前批次数据index += batchSize;if (index < data.length) {setTimeout(processBatch, 0); // 使用宏任务拆分处理}}processBatch();
    }
    

5. 微任务 vs 宏任务的关键区别

特性微任务(Microtask)宏任务(Macrotask)
执行时机当前任务结束后立即执行(在渲染前)下一次事件循环开始时执行(可能在渲染后)
队列清空规则一次性清空所有微任务每次只处理一个宏任务
触发频率高(可能在一次事件循环中多次触发)低(每次事件循环只处理一个)
典型场景Promise回调、DOM变更监听定时器、I/O操作、UI渲染

6. 注意事项

  1. 微任务阻塞渲染:如果微任务队列过长,会导致UI长时间无法渲染,造成页面卡顿。
  2. 合理选择任务类型
    • 需要立即执行的异步操作(如Promise链)使用微任务。
    • 需要离散执行的操作(如定时器、大数据处理)使用宏任务。
  3. 浏览器兼容性queueMicrotask 是较新的API,旧浏览器可能需要使用 Promise.resolve().then() 替代。

通过理解微任务和宏任务的执行机制,你可以更精确地控制代码的执行顺序,避免性能问题,提升用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89314.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring-AI系列-AI模型-Model

原文-知识库&#xff0c;欢迎大家评论互动 AI Model API Portable ModelAPI across AI providers for Chat, Text to Image, Audio Transcription, Text to Speech, and Embedding models. Both synchronous and stream API options are supported. Dropping down to access mo…

MySQL查询今天、昨天、上周、近30天、去年等的数据的方法

目录 常用的MySQL查询今天、昨天、上周、近30天、去年等数据的方法 0、Sql server中DateDiff()用法 1、MySQL的DATE_SUB()函数 定义和用法 语法 实例 2、MySQL的TO_DAYS(date) 3、MySQL的DATE() 函数 定义和用法 4、MySQL NOW() 函数 定义和用法 语法 实例 例子 …

Linux —— B / 基础开发工具

一、软件包管理器1.1什么是软件包1.2 Linux软件生态1.3 yum具体操作1.3.1 查看软件包1.3.2 安装软件1.3.3 卸载软件1.3.4 注意事项1.4 安装源二、编辑器Vim2-1 Linux编辑器-vim使用2-2 vim的基本概念2-3 vim的基本操作2-4 vim正常模式命令集2-5 vim末行模式命令集2-6 vim操作总…

SQL,在join中,on和where的区别

0.结论 两个表在&#xff0c;join时&#xff0c;首先做一个笛卡尔积&#xff0c;on后面的条件是对这个笛卡尔积做一个过滤形成一张临时表&#xff0c;如果没有where就直接返回结果&#xff0c;如果有where就对上一步的临时表再进行过滤。 先on&#xff0c;再join&#xff0c;再…

SD-WAN在储能网络中的应用,传统方案如何借力智能化升级?(附网络架构图)

一、储能网络的建设挑战在储能项目中&#xff0c;网络系统通常需要实现以下目标&#xff1a;高可靠性&#xff1a;实时采集和传输储能设备状态数据&#xff0c;链路中断可能导致系统故障。灵活扩展&#xff1a;分布式站点部署广泛&#xff0c;传统网络扩展需重新铺设线路&#…

Oracle11.2.0.4 RAC迁移升级Oracle19.3 RAC

问题描述 填写问题的基础信息。 系统名称 Oracle11.2.0.4迁移升级Oracle19.3 IP地址 操作系统 Centos7.5 数据库 Oracle11.2.0.4迁移升级Oracle19.3 症状表现 问题的症状表现如下 需要将单机的Oracle11.2.0.4环境升级到Oracle19.3.0RAC环境&#xff0c;采用迁移升级的…

SAP-ABAP:SAP的‘cl_http_utility=>escape_url‘对URL进行安全编码方法详解

SAP的’cl_http_utility>escape_url’对URL进行安全编码方法详解 核心作用&#xff1a;对 URL 进行安全编码&#xff0c;将特殊字符转换为 %XX 格式&#xff0c;确保符合 HTTP 传输规范。1. 功能与作用 ✅ URL 安全编码 将非安全字符转换为十六进制 ASCII 码&#xff08;%XX…

基于HarmonyOS的智能灯光控制系统设计:从定时触发到动作联动全流程实战

摘要 随着智能家居的快速普及&#xff0c;人们对居住环境的智能化需求越来越高&#xff0c;其中智能灯光控制是最基础、也是最常用的功能之一。从最初的远程控制发展到如今能“感知环境、自动响应”的智能灯光系统&#xff0c;背后依赖的是强大的系统联动能力。鸿蒙系统作为面向…

ROS1/Linux——linux虚拟机主ip地址:网络信息不可用

ROS1/Linux——linux虚拟机主ip地址&#xff1a;网络信息不可用 文章目录ROS1/Linux——linux虚拟机主ip地址&#xff1a;网络信息不可用参考亿点链接问题描述最终解决方案参考亿点链接 Unable to fetch some archives, maybe run apt-get update or try with –fix-missingli…

ssl相关命令生成证书

当前环境 OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025) GmSSL 3.1.2 Dev 本地gmssl命令 #生成证书公私钥对 gmssl sm2keygen -pass 1234 -out sm2.key -pubout sm2pub.pem #使用certgen命令生成自签名证书cert.crt gmssl certgen -C CN -ST Beijing -L Ha…

TensorFlow深度学习实战——DCGAN详解与实现

TensorFlow深度学习实战——DCGAN详解与实现0. 前言1. DCGAN 架构2. 构建 DCGAN 生成手写数字图像2.1 生成器与判别器架构2.2 构建 DCGAN相关链接0. 前言 深度卷积生成对抗网络 (Deep Convolutional Generative Adversarial Network, DCGAN) 是一种基于生成对抗网络 (Generati…

SpringBoot 使用MyBatisPlus

引入依赖<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.3.0</version> </dependency>写一个interface 继承basemapMapper public in…

Git 中如何查看提交历史?常用命令有哪些?

回答重点在 Git 中&#xff0c;我们可以使用 git log 命令来查看提交历史。这个命令会列出所有的提交记录&#xff0c;显示每个提交的哈希值、作者信息、提交时间和提交信息。常用的 git log 命令及其选项有&#xff1a;1&#xff09; git log &#xff1a;显示完整的提交历史。…

Flink数据流高效写入MySQL实战

这段代码展示了如何使用 Apache Flink 将数据流写入 MySQL 数据库&#xff0c;并使用了 JdbcSink 来实现自定义的 Sink 逻辑。以下是对代码的详细解析和说明&#xff1a;代码结构包声明&#xff1a;package sink定义了代码所在的包。导入依赖&#xff1a;导入了必要的 Flink 和…

MATLAB下载安装教程(附安装包)2025最新版(MATLAB R2024b)

文章目录前言一、MATLAB R2024b下载二、MATLAB下载安装教程前言 MATLAB R2024b 的推出&#xff0c;进一步提升了其在工程实践中的实用性和专业性。它不仅提供了更多针对特定工程领域的解决方案&#xff0c;还在性能和兼容性方面进行了显著改进。 本教程将一步一步引导完成 MA…

Linux 基础命令学习,立即上手Linux操作

Linux 基础命令学习本文挑选最常用、最容易上手的 Linux 命令。每条都附带一句话说明 真实示例&#xff0c;直接复制即可练习&#xff0c;零基础也能跟得上。1  先掌握 目录导航&#xff1a;pwd / ls / cdpwd – 显示当前所在目录 pwd # 输出示例 /home/yournamels ‑a…

Android构建流程与Transform任务

1. 完整构建流程概览 1.1 主要构建阶段 预构建阶段 → 代码生成阶段 → 资源处理阶段 → 编译阶段 → Transform阶段 → 打包阶段1.2 详细任务执行顺序 ┌─────────────────────────────────────────────────────────…

CKS认证 | Day6 监控、审计和运行时安全 sysdig、falco、审计日志

一、分析容器系统调用&#xff1a;Sysdig Sysdig&#xff1a;定位是系统监控、分析和排障的工具&#xff0c;在 linux 平台上&#xff0c;已有很多这方面的工具 如tcpdump、htop、iftop、lsof、netstat&#xff0c;它们都能用来分析 linux 系统的运行情况&#xff0c;而且还有…

Redis:持久化配置深度解析与实践指南

&#x1f9e0; 1、简述 Redis 是一款基于内存的高性能键值数据库&#xff0c;为了防止数据丢失&#xff0c;Redis 提供了两种主要的持久化机制&#xff1a;RDB&#xff08;快照&#xff09;和 AOF&#xff08;追加日志&#xff09;。本文将从原理到配置&#xff0c;再到实际项目…

共创 Rust 十年辉煌时刻:RustChinaConf 2025 赞助与演讲征集正式启动

&#x1f680; 共创 Rust 十年辉煌时刻&#xff1a;RustChinaConf 2025 赞助与演讲征集正式启动2025年&#xff0c;是 Rust 编程语言诞生十周年的里程碑时刻。在这个具有历史意义的节点&#xff0c;RustChinaConf 2025 携手 RustGlobal 首次登陆中国&#xff0c;联合 GOSIM HAN…