JS 是单线程语言。这句话对不对?

按照目前的情况来看,JS 自从支持了 Web Worker 之后,就不再是单线程语言了,但 Worker 的工作线程与主线程有区别,在 Worker 的工作线程中无法直接操作 DOM、window 对象或大多数浏览器 API(如 localStorage),Worker 的全局对象也不再是 window 对象,而是 self。

Worker 中的事件循环与主线程相互独立,互不影响,但执行顺序还是得遵循 JS 的语法规则。

宏任务

宏任务表示执行时间较长的任务,在每次时间循环时只会执行一个宏任务,执行完毕后处理微任务队列,所有微任务都执行完毕后进入下一个宏任务。

JS 常见宏任务类型:

  1. 定时器任务:setTimeout / setInterval

  2. DOM 事件回调(如 click、scroll)

  3. I/O 操作(如文件读取、网络请求)

  4. 浏览器用于执行动画的方法 requestAnimationFrame ,执行时机与渲染相关

  5. Node.js 环境的 setImmediate

  6. script 标签内主线程的同步代码(整体作为一个宏任务)

微任务

微任务表示更轻量的异步任务,当宏任务执行完毕之后立即执行。

JS 常见微任务类型:

  1. Promise.then() / Promise.catch() / Promise.finally()

  2. 浏览器监听 DOM 变化的 API 对象,比如:MutationObserver

  3. 手动添加微任务API方法:queueMicrotask()

  4. nodejs 中的 process.nextTick()

代码解析

看这么一段代码:

(function() {console.log(1)setTimeout(() => { console.log(2); });queueMicrotask(() => console.log(3))new Promise(resolve => {console.log(4);setTimeout(() => {resolve();console.log(5);}, 0);Promise.resolve().then(() => console.log(6));console.log(7);}).then(() => {console.log(8);Promise.resolve().then(() => console.log(9));});console.log(10);
})();

分析代码:

(function() {console.log(1) // 同步任务setTimeout(() => { console.log(2); });queueMicrotask(() => console.log(3))new Promise(resolve => {console.log(4); // 同步任务setTimeout(() => { // 宏任务resolve(); // 宏任务的同步任务console.log(5); // 宏任务中的同步任务}, 0);Promise.resolve().then(() => console.log(6)); // 微任务console.log(7); // 同步任务}).then(() => { // 微任务console.log(8); // 微任务中的同步任务Promise.resolve().then(() => console.log(9)); // 微任务中的微任务});console.log(10); // 同步任务
})();

第一轮

首先同步代码的宏任务优先级最高,不管微任务还是宏任务,同步代码都会先执行。

所以上面代码会优先执行:

console.log(1)
console.log(4);
console.log(7);
console.log(10);

接着开始处理微任务:

queueMicrotask(() => console.log(3))
Promise.resolve().then(() => console.log(6));

微任务处理完,开始执行下一轮宏任务。

第二轮

这一轮中的宏任务只有一个 setTimeout,执行完之后由于没有微任务队列,所以直接执行下一轮宏任务。

setTimeout(() => { console.log(2); });

第三轮

这一轮的宏任务中有同步代码。

setTimeout(() => { // 宏任务resolve(); // 宏任务的同步任务console.log(5); // 宏任务中的同步任务
}, 0);

在执行完 resolve() 之后,会将 Promise.then 的回调函数放入微任务队列中,所以在宏任务执行完之后会开始微任务:

then(() => { // 微任务console.log(8); // 微任务中的同步任务Promise.resolve().then(() => console.log(9)); // 微任务中的微任务
})

最终的打印顺序

1
4
7
10
3
6
2
5
8
9

执行流程图

JS 代码逐行执行,在遇到宏任务时,整个代码块丢到宏任务队列,在遇到微任务时,将微任务丢到本次事件循环中的微任务队列,本次事件循环执行完之后,再执行微任务队列中的任务,微任务执行完之后开始下一个宏任务执行。

JS 代码执行机制:

宏任务执行机制:

写在最后

JS 中的代码执行流程永远都是事件循环机制,这是 JS 的任务调度核心,理解事件循环机制,才能在开发中游刃有余~~

文章转载自:前端路引

原文链接:Web前端入门第 68 问:JavaScript 事件循环机制中的微任务与宏任务 - 前端路引 - 博客园

体验地址:JNPF快速开发平台

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

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

相关文章

【论文笔记】【强化微调】TinyLLaVA-Video-R1:小参数模型也能视频推理

[2504.09641] TinyLLaVA-Video-R1: Towards Smaller LMMs for Video Reasoning 1. 引述 继之前的一篇 Video-R1 的工作,一篇新的关于视频推理的工作很快就上传到 Arxiv 上 “占坑” 了,这个工作是关于使用小参数(3B)的 LLM 进行视…

基于元学习的回归预测模型如何设计?

1. 核心设计原理 目标:学习一个可快速适应新任务的初始参数空间,使模型在少量样本下泛化。数学基础: MAML框架: min ⁡ θ ∑ T ∼ p ( T ) [ L T ( f θ − η ∇ θ L T ( f θ ( D T t r a i n ) ) ( D T t e s t ) ) ] \min…

MyBatis Plus与P6Spy日志配置

前言 在开发基于Spring Boot和MyBatis Plus的项目时,日志功能是调试和优化SQL查询的核心工具。通过合理配置日志输出,开发者可以直观查看生成的SQL语句、执行时间、参数值以及潜在的性能瓶颈。 一、MyBatis Plus日志配置 1.1 基础配置:直接…

SpringCloudGateway(spel)漏洞复现 Spring + Swagger 接口泄露问题

环境配置 gateway Spring Cloud : 这个就是分布式的微服务组件 微服务 : 一般指的是独立的,专注于一项功能的服务 Gateway 这个其实是个云端的网关配置(他的作用就是对访问web的流量进行防护比如一些爬虫的阻截&#xff0…

服务器手动安装并编译R环境库包:PROJ→RGDAL

目录 方式1:conda-forge安装错误:缺乏libnsl.so.1✅ 方法一:查找系统中是否已有此库替补方案:采用libnsl.so.3链接 libnsl.so.1✅ 方法二:系统中没有安装 libnsl.so.1 → 手动安装✅ 方法三:使用 Conda 安装…

教育技术学读计算机论文的提示词

角色: 你是一位经验丰富的计算机专业教授,擅长用通俗易懂的语言向初学者解释复杂概念。我现在正在学习阅读计算机科学领域的算法论文,但我的基础比较薄弱(了解编程基础如变量、循环、函数,了解一点数据结构和算法概念如数组、链表、排序,但对高级术语和数学证明不熟悉)。…

棋盘格标定板和圆形标定板的优劣性

来源:deepseek 在相机标定中,棋盘格标定板和圆形标定板(或圆点阵列标定板)是最常用的两种类型。它们各有优劣,选择哪种取决于具体的应用场景、需求以及使用的标定算法。以下是它们的主要优劣对比: &#…

2025年UDP洪水攻击防御指南:从7.3Tbps攻防战看原理与实战

45秒37.4TB流量!一场刷新历史纪录的DDoS攻击正在颠覆传统防御体系 一、什么是UDP洪水攻击? UDP洪水攻击(UDP Flood)是一种利用用户数据报协议(UDP) 的无连接特性发起的分布式拒绝服务(DDoS&…

一种集成统计、视觉和基于规则方法的新型可解释医学图像分类人工智能框架|文献速递-最新论文分享

Title 题目 A novel explainable AI framework for medical image classificationintegrating statistical, visual, and rule-based methods 一种集成统计、视觉和基于规则方法的新型可解释医学图像分类人工智能框架 01 文献速递介绍 人工智能(AI)…

洛谷 P10113 [GESP202312 八级] 大量的工作沟通-普及/提高-

题目描述 某公司有 N N N 名员工,编号从 0 0 0 至 N − 1 N-1 N−1。其中,除了 0 0 0 号员工是老板,其余每名员工都有一个直接领导。我们假设编号为 i i i 的员工的直接领导是 f i f_i fi​。 该公司有严格的管理制度,每位…

数组题解——移除元素​【LeetCode】

27. 移除元素 快慢指针法 算法思路 使用双指针(fast和slow)遍历数组。 fast指针遍历每一个元素。slow指针指向下一个将被保留的位置。 如果nums[fast] ! val,就把nums[fast]赋值到nums[slow],并将slow向前移动一位。遍历结束后…

ubuntu20.04安装多版本python时,如何使用sudo python3.10

sudo 命令只会加载基本的path和动态库,自己定义的不会加入,因此会出现使用sudo运行多版本python出现奇怪的现象,进行如下操作就可以使用 sudo vi ~/.bashrc alias sudosudo env PATH$PATH LD_LIBRARY_PATH$LD_LIBRARY_PATH 使用 sudo visud…

统计学纯基础(1)

⛄统计分析分为统计描述与统计推断,统计推断分为总体估计与假设检验 🏂16:45 医学研究--基础研究、转化医学研究、临床研究 临床研究--病因学研究、诊断准确性试验、预后研究、疗效研究 一般认为3个月以内的预后属于近期预后,…

接口自动化测试之pytest 运行方式及前置后置封装

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、Pytest 优点认知 1.可以结合所有的自动化测试工具 2.跳过失败用例以及失败重跑 3.结合allure生产美观报告 4.和Jenkins持续集成 5.很多强大的插件 pytest-htm…

利用folium实现全国高校分布地图显示

智汇中国 | 揭秘!一张地图带你遨游全国高校殿堂 大家好,这期我们来利用folium模块实现全国高校分布的地图显示。 什么是Folium Folium为Python用户提供了便捷的方式来利用Leaflet.js的强大地图可视化功能,而无需直接编写JavaScript代码。它允许开发者以Pythonic的方式处理…

【和春笋一起学C++】(二十二)C++函数新特性——函数重载

目录 函数重载的含义 重载函数使用注意事项 几种特殊情况 函数重载的含义 函数重载使得能够用不同的参数列表调用多个同名的函数。可以通过函数重载设计一系列函数,它们完成相同的工作,但使用不同的参数列表。 函数重载的关键是函数的参数列表——也被称为函数特征标。如…

CrewAI多智能体框架的实操教程-旅行规划-2

1、创建一个新的 CrewAI 项目 surprise_trip crewai create crew surprise_trip 选择模型厂商和模型 生成.env MODELgpt-4o OPENAI_API_KEY你的api_keySERPER_API_KEY你的SERPER api_key 2、探索项目结构 3、配置代理 修改 agents.yaml文件。 # 个性化活动规划师 Agent p…

vue脚手架与前后端交互

前言 。Vue.js作为一种流行的前端框架,提供了丰富的功能和灵活的架构,方便了开发者进行高效的开发。为了更好地使用Vue,Vue CLI(脚手架工具)成为了开发者进行项目创建和管理的重要工具。本文将结合Vue脚手架的使用场景…

【麻省理工】《how to speaking》笔记

【【麻省理工】《如何说话》一节课教你成为表达的王者】 开始 在演讲最开始的时候,你要告诉观众,在接下来的15分钟或一个小时之内,他们将会学到什么东西。这会让观众集中注意力去倾听。 PPT 你的幻灯片上的字要越少越好。因为听众的大脑一…

ESP32-HTML-08

一、html显示图片 1.工程包含Html需要显示的图片 2、CMakeLists.txt包含图片资源 举例&#xff1a; idf_component_register(SRCS main.cEMBED_FILES root.html favicon.ico) 3.html中图片的标签 <img src"motus.ico"> 4.后台代码的添加 static esp_e…