事件循环机制(Event Loop)和宏任务(macro-tast)微任务(micro-tast),详细讲解!!!
“事件循环机制” 和 “宏任务微任务” 也是前端面试中常考的面试题了。
首先,要深刻理解这些概念的话,需要回顾一些知识点。
知识点回顾
1、进程与线程
进程。
程序运行需要有它自己的专属内存空间,可以把这块内存空间简单的理解为进程
每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。
线程。
线程是CPU的基本调度单位,是程序执行的一个完整流程。
一个进程至少有一个线程,所以在进程开启后会自动创建一个线程来运行代码,该线程称之为 主线程。
如果程序需要同时执行多块代码,主线程就会开启更多的线程来执行代码,所以一个进程中可以包含多个线程。
简单总结一些它们的关系:
一个进程中一般至少有一个运行的线程——主线程
一个进程中也可以同时运行多个线程
多个进程之间的数据是不能同时直接共享的
那浏览器有哪些进程与线程呢?
浏览器内部的工作其实极为复杂,它是多进程多线程的。且为了避免相互影响,它会自动启动多个进程。
比如,我们可以在浏览器任务管理器查看一下所有进程。

其中,最主要的进程有:
浏览器进程
主要负责界面显示、用户交互、子进程管理等。浏览器进程内部会启动多个线程处理不同的任务。
网络进程
负责加载网络资源。网络进程内部会启动多个线程来处理不同的网络任务
渲染进程
渲染进程启动后,会开启一个 渲染主线程,主线程负责执行 HTML、CSS、JS代码
默认情况下,浏览器会为每一个标签页开启一个新的渲染进程,以保证不同的标签页之间不互相影响。
2、JS是单线程还是多线程?
JS肯定是单线程的。
如果是多线程会发生什么? 如果JS是多线程,那当两个线程同时对dom进行操作,一个是添加事件,一个是删除dom,要怎么处理? 所以为了避免这种情况,JS选择只用一个主线程来执行代码以保证一致性。
3、怎么去理解JS的异步?
上面写到JS是单线程的,它运行在浏览器的渲染主线程中,且渲染主线程有且仅有一个。 但是它却有很多任务,比如渲染页面、执行JS都包含在内。
那如果不使用异步,而是同步的方式,就极有可能造成主线程的阻塞,那其他任务就无法执行了,一方面消耗时间,另一方面页面又没法及时更新,很容易有卡死现象。
所以浏览器采用异步方式。 具体做法其实就是, 比如一些任务发生了,假设现在遇到了计时器,主线程会将任务交给其他线程处理,自己立马结束这个任务,转而执行后续代码。 而等其他线程完成后,将事先传递的回调函数包装成任务,再加入到消息队列的末尾排队,等待主线程的调度执行。
在这种异步模式下,浏览器就可以避免阻塞。
这一段解释涉及到操作系统的进程调度问题和我们所要理解的事件循环机制。暂时看不懂的,可以先往下看。
4、进程调度
进程调度的知识点稍多,比如抢占式调度,非抢占式调度,先来先服务,优先级调度等等。
我们这里就简单介绍一下先来先服务(FCFS)。
它的算法思想其实就是从“公平”的角度来考虑的 (我们可以理解成 排队买东西,先来排队的优先买)。所以它的算法规则,其实是按照 作业/进程 到达的先后顺序进行服务。 它是一种非抢占式算法 (可以理解成 “不允许你插队”),它不会导致 “饥饿”现象(也就是一直轮不到执行,苦苦等待),因为只要排队终有一天会轮到它的。
事件循环机制
介绍完一些知识点后,再理解一下主角“事件循环机制”
我们在前面说了,浏览器会通过渲染主线程去执行JS
在最开始的时候,渲染主线程会进入一个无限的循环中
每一次的循环,都会检查一下消息队列中是否存在任务。 如果存在任务,就取出第一个任务执行,执行完一个后进入下一次循环; 如果没有,就进入等待态(休眠)
其他所有线程(包括其他进程的线程)可以随时向消息队列添加任务,如果主线程是等待态,会将其唤醒以继续循环拿取任务执行。
这种过程,也就被称为 事件循环(消息循环)
在上面的过程中,我们先简单的将消息队列理解成一个队列(虽然有具体划分)。 而队列的特性是先进先出,比如我们按顺序执行代码,分别遇到了 加法任务、输出任务、乘法任务。 那他们依次入队,渲染主线程循环获取任务也是按照这个顺序去执行的
宏任务和微任务
在上面为了便于简单的理解,说是当成一个队列,其实不是的。 JS中用来存储代执行回调函数的队列可以分为2种不同的队列,那就是 宏队列 和 微队列。 顾名思义就是分别用来保存待执行的宏任务和微任务(回调)。
常见的宏任务包括:
setTimeout
setInterval
script(整体代码)
I/O操作
等等
微任务包括:
Promise
Mutation
等等
既然会划分成2个队列,那肯定是要在JS执行时区别对待它们的。 JS引擎首先必须先执行所有的初始化同步任务, 在每次准备取出第一个宏任务执行前,都要看看有没有微任务,要一个个取出来执行。 当该宏任务执行完毕后,会检查其中的微任务队列,如果没有,那就直接执行下一个宏任务,如果不为空,那就依次执行微任务,执行完毕再执行下一个宏任务。
所以引入微任务的初衷是为了解决异步回调的问题。(其实我们可以理解为 微任务的优先级比较高,根据优先级调度算法,调度时会选优先级最高的进行调度执行)
即然说到优先级,就必须要提一下。
任务本身是没有优先级的,都是遵循先来先服务算法。 但是 消息队列是有优先级的。 也就是上面我们所说的 微队列比宏队列优先级高。所以每执行一次宏任务,都要看看有没有微任务的存在。
但随着浏览器复杂的提升,W3C似乎不再采用宏队列的说法。 而是至少分为了 延时队列、交互队列、微队列。 (它们优先级是从低到高的,微队列优先级最高)。具体内容可能还需要看一下官方解释。
如果我们想把一个函数添加到微队列,可以这么写
Promise.resolve().then(函数)基本的介绍就结束了,应该差不多可以理解这些概念了。接下来可以看一道简单的题
<h1>Eric is handsome</h1>
<button>change</button><script>var h1 = document.querySelector('h1');var btn = document.querySelector('button');// 死循环指定时间function delay(duration){var start = Date.now();while(Date.now() - start < duration) {}}btn.onclick = function() {h1.textContent = "Eric真帅";delay(3000);}
</script>对于以上代码,当我们点击按钮后,会发生什么呢?
实际上,点击完按钮后,需要经过3秒,h1的文本才会发生变化。
因为对于渲染主线程而言,运行解析JS代码以后,会用交互线程去监听按钮的点击事件。 (假设我们在某一个时刻点击了它,此时消息队列中没有其他任务)
那交互线程会将这个function作为一个任务,假设记为fn,添加至消息队列中。 渲染主线程会被唤醒从而调用fn任务。 所以可以执行function里面的代码了。 首先是h1.textContent = “Eric真帅”,fn任务会产生一个绘制任务(也就是改变h1文本),那这个绘制任务就会到消息队列中进行排队,此时fn任务继续执行到下一行 delay(3000),也就是被阻塞了3秒。3秒后,fn执行完毕,进行循环,这时候获取了消息队列中的绘制任务,调度执行,文本发生改变。
如果有帮助的话,可以点赞收藏哦~~~
相关文章:
事件循环机制(Event Loop)和宏任务(macro-tast)微任务(micro-tast),详细讲解!!!
“事件循环机制” 和 “宏任务微任务” 也是前端面试中常考的面试题了。首先,要深刻理解这些概念的话,需要回顾一些知识点。知识点回顾1、进程与线程进程。 程序运行需要有它自己的专属内存空间,可以把这块内存空间简单的理解为进程每个应用至…...
mysql基础操作3
查询襄阳的员工姓名和性别,性别要求显示为 男 女SELECT ename,(CASE WHEN sexF THEN 女 ELSE 男 END)sexFROM empWHERE jiguan襄阳查询所有的订单,显示订单日期 订单数量 订单状态SELECT saleDate,salesQuantity,(CASE WHEN saleState1 THEN 新建 WHEN s…...
【Web安全】PHP安全
一、文件包含漏洞严格来说,文件包含就是代码注入的一种。代码注入,其原理就是注入一段用户能控制的脚本或代码并让服务器端执行。代码注入的典型代表就是文件包含。文件包含可能会出现在JSP、PHP、ASP等语言中,常见函数如下:PHP&a…...
双向链表+循环链表
循环链表双向链表 循环链表 循环链表是头尾相接的链表(即表中最后一个结点的指针域指向头结点,整个链表形成一个环)(circular linked list) **优点:**从表中任一结点出发均可访问全部结点 循环链表与单链表的主要差别当链表遍历时,判别当前…...
Java程序的逻辑控制
一、顺序结构 顺序结构比较简单,如果我们按照代码书写的顺序一行一行执行,将会是这样的: System.out.println("aaa"); System.out.println("bbb"); System.out.println("ccc"); // 运行结果 aaa bbb ccc 如…...
BUCTOJ - 2023上半年ACM蓝桥杯每周训练题-1-A~K题C++Python双语版
文章目录BUCTOJ - 2023上半年ACM&蓝桥杯每周训练题-1-A~K题CPython双语版前言问题 A: 1.2 神奇兔子数列题目描述输入输出解题思路AC代码CPython问题 B: 1.3 马克思手稿中的数学题题目描述输入输出解题思路AC代码CPython问题 C: 1.4 爱因斯坦的阶梯题目描述输入输出解题思路…...
存储的本质-学习笔记
1 经典案例 1.1 数据的流动 一条用户注册数据流动到后端服务器,持久化保存到数据库中。 1.2 数据的持久化 校验数据的合法性修改内存写入存储介质2 存储&数据库简介 2.1 存储系统特点 性能敏感、容易受硬件影响、存储系统代码既“简单”又“复杂”。 2.2 数…...
新一代骨传导机皇重磅发布:南卡Neo骨传导运动耳机,性能全面提升
近日,中国最强骨传导品牌NANK南卡发布了最新一代骨传导耳机——南卡Neo骨传导耳机!该款耳机与运动专业性更强的南卡runner Pro4略微不同,其主要定位于轻运动风格,所以这款耳机的音质和佩戴舒适度达到了令人咂舌的地步!…...
Hbase Schema设计与数据模型操作
一、Hbase Schema设计 1,Schema 创建 使用 Apache HBase Shell 或使用 Java API 中的 Admin 来创建或更新 HBase 模式。 Configuration config HBaseConfiguration.create(); Admin admin new Admin(conf); TableName table TableName.valueOf("myTable&…...
微电影广告有哪些传播优势?
微电影广告是在基于微电影的模式下发展而来的,是伴随着当下快节奏、碎片化的生活方式而诞生的新兴广告表现形式。微电影广告凭借其具备的独特传播优势以及时代特征成为广大企业主塑造企业品牌形象的主要方式。那么,微电影广告究竟有哪些传播优势…...
html基础(列表(ul、ol、dl)、表格table、表单(input、button、label)、div和span、空格nbsp)
1无序列表<ul>和有序列表<ol>1.1无序列表<ul><!-- 无序列表 --><ul><li>吃饭</li><li>睡觉</li><li>打豆豆</li></ul>1.2有序列表<ol><!-- 有序列表 --><ol><li>吃饭</li…...
uniapp常用标签
view ~~ 视图容器类似于传统html中的div,用于包裹各种元素内容<view><text>hh</text> </view>scroll-view ~~可滚动视图区域scroll-x 允许横向滚动scroll-y 允许纵向滚动scroll-top 设置竖向滚动条位置,可以一键回到顶部refresh…...
《数字中国建设整体布局规划》发布,推进IPv6部署和应用是重点
近日,中共中央、国务院印发了《数字中国建设整体布局规划》(以下简称《规划》),并发出通知,要求各地区各部门结合实际认真贯彻落实。 《规划》指出,建设数字中国是数字时代推进中国式现代化的重要引擎&…...
【Java】 异步调用实践
本文要点: 为什么需要异步调用CompletableFuture 基本使用RPC 异步调用HTTP 异步调用编排 CompletableFuture 提高吞吐量BIO 模型 当用户进程调用了recvfrom 这个系统调用,kernel 就开始了 IO 的第一个阶段:准备数据。对于 network io 来说…...
园区智慧能源管理系统
实现对园区的用能情况实时、全方位监测,重点设备进行数据自动采集并智能统计、分析,根据需要绘制各种趋势曲线、能源流向图和分析报表。将物联网、大数据与全过程能源管理相融合,提供全生命周期的数字化用能服务,实现用能的精细化…...
基于卷积神经网络CNN的分类研究,基于卷积神经网络的手写体识别
目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN手写体识别 基本结构 主要参数 MATALB代码 结果图 展望 背影 现在生活,各种人工智能都要求对图像拥有识别…...
mybatis的增删改查运用
目录 一、总览图 二、运用 一、总览图 代码总览图 数据库总览图 二、运用 数据库的一张表对应一个封装类,一个mapper接口,一个mapper.xml文件, 一个实现类。表中的增删改查都在里面编写 但是配置xml文件整个数据库只要一个就好了 1.…...
centos8安装docker运行java文件
本文由个人总结,如需转载使用请标明原著及原文地址 这里是基于我前一篇搭的centos8服务器做的,如果yum baseos源或appstream源有问题可以去看看前一篇 https://blog.csdn.net/qq_36911145/article/details/129263830 1.安装docker 1.1配置docker yum…...
Docker容器化部署.net core API
1.为API集成Docker环境。(VS自带,傻瓜式操作) 1.1 点击项目,右键,添加,选择Docker支持 1.2 找到项目根目录中的Dockerfile文件,这是VS刚刚帮我们自动生成的。进入和做如图标红地方修改。 把文…...
springcloud 服务调用feign、熔断hystrix、网关gateway
回归cloud的学习,对于springcloud的架构与原理以及性能的分析我们都在之前的文章里写过:springcloud架构的认识我们之前测试过eureka服务注册功能,它能很好的保存服务之间的通讯关系,是维系微服务通讯网之间的电话本,同…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
