01_原理-事件循环
01_原理-事件循环
文章目录
- 01_原理-事件循环
 - 一、浏览器的进程模型
 - ①:何为进程?
 - ②:何为线程?
 - ③:浏览器有哪些进程和线程?
 
- 二、渲染主线程是如何工作的?
 - 三、若干解释
 - ①:何为异步?
 - ②:JS为何会阻碍渲染?
 - ③:任务有优先级吗?
 - ④:js优先级案例
 
一、浏览器的进程模型
①:何为进程?
程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程
②:何为线程?
有了进程后,就可以运行程序的代码了。
运行代码的「人」称之为「线程」。
一个进程至少有一个线程,所以在进程开启后会自动创建一个线程来运行代码,该线程称之为主线程。
如果程序需要同时执行多块代码,主线程就会启动更多的线程来执行代码,所以一个进程中可以包含多个线程。
③:浏览器有哪些进程和线程?
浏览器是一个多进程多线程的应用程序
浏览器内部工作极其复杂。
为了避免相互影响,为了减少连环崩溃的几率,当启动浏览器后,它会自动启动多个进程。

1.可以在浏览器的任务管理器中查看当前的所有进程

其中,最主要的进程有:
 1.浏览器进程
 主要负责界面显示、用户交互、子进程管理等。刻览器进程内部会启动多个线程处理不同的任务。
2.网络进程
 负责加载网络资源。网络进程内部会启动多个线程来处理不同的网络任务。
3.渲染进程(本节课重点讲解的进程)
 渲染进程启动后,会开启一个渲染主线程,主线程负责执行HTML、CSS、JS代码。
 默认情况下,浏览器会为每个标签页开启一个新的渲染进程,以保证不同的标签页之间不相互影响。
将来该默认模式可能会有所改变,有兴趣的同学可参见chrome官方说明文档
二、渲染主线程是如何工作的?
渲染主线程是浏览器中最繁忙的线程,需要它处理的任务包括但不限于:
- 解析HTML
 - 解析cSS
 - 计算样式
 - 布局
 - 处理图层
 - 每秒把页面画60次
 - 执行全局JS代码
 - 执行事件处理函数
 - 执行计时器的回调函数
 - 等·······
 
思考题:为什么渲染进程不适用多个线程来处理这些事情?
要处理这么多的任务,主线程遇到了一个前所未有的难题:如何调度任务?
比如:
-  
我正在执行一个JS函数,执行到一半的时候用户点击了按钮,我该立即去执行点击事件的处理函数吗?
 -  
我正在执行一个JS函数,执行到一半的时候某个计时器到达了时间,我该立即去执行它的回调吗?
 -  
浏览器进程通知我“用户点击了按钮”,与此同时,某个计时器也到达了时间,我应该处理哪一个呢?
 
渲染主线程想出了一个绝妙的主意来处理这个问题:排队
- 在最开始的时候,渲染主线程会进入一个无限循环
 - 每一次循环会检查消息队列中是否有任务存在。如果有,就取出第一个任务执行,执行完一个后进入下一次循环;如果没有,则进入休眠状态。
 - 其他所有线程(包括其他进程的线程)可以随时向消息队列添加任务。新任务会加到消息队列的未尾。在添加新任务时,如果主线程是休眠状态,则会将其唤醒以继续循环拿取任务
 
这样一来,就可以让每个任务有条不紊的、持续的进行下去了。
三、若干解释
①:何为异步?
代码在执行过程中,会遇到一些无法立即处理的任务,比如:
- 计时完成后需要执行的任务 – 
setTimeout setInterval - 网络通信完成后需要执行的任务 – 
XHR、Fetch - 用户操作后需要执行的任务 – 
addEventListener 
如果让渲染主线程等待这些任务的时机达到,就会导致主线程长期处于「阻塞」的状态,从而导致浏览器「卡死」
渲染主线程承担着极其重要的工作,无论如何都不能阻塞!
使用异步的方式,渲染主线程永不阻塞
面试题:如何理解JS的异步?
参考答案:
JS是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个。
而渲染主线程承担着诸多的工作,渲染页面、执行JS都在其中运行
如果使用同步的方式,就极有可能导致主线程产生阻塞,从而导致消息队列中的很多其他任务无法得到执行。
这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致页面无法及时更新,给用户造成卡死现
象。
所以浏览器采用异步的方式来避免。具体做法是当某些任务发生时,比如计时器、网络、事件监听,主线程将
任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。当其他线程完成时,将事先传递的
回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行
在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行
②:JS为何会阻碍渲染?
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>Coke</h1>
<button>按钮</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 = 'Coke很帅!'delay(3000)
};
</script>
</body>
</html>
 

③:任务有优先级吗?
任务没有优先级,在消息队列中先进先出
但消息队列是有优先级的
根据W3C的最新解释:
-  
每个任务都有一个任务类型,同一个类型的任务必须在一个队列,不同类型的任务可以分属于不同的队列。在一次事件循环中,浏览器可以根据实际情况从不同的队列中取出任务执行。
 -  
浏览器必须准备好一个微队列,微队列中的任务优先所有其他任务执行
https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint 
随着浏览器的复杂度急剧提升,W3C不再使用宏队列的说法
在目前chrome的实现中,至少包含了下面的队列:
- 延时队列:用于存放计时器到达后的回调任务,优先级「中」
 - 交互队列:用于存放用户操作后产生的事件处理任务,优先级「高」
 - 微队列:用户存放需要最快执行的任务,优先级「最高」
 
添加任务到微队列的主要方式主要是使用Promise、MutationObserver
例如:
//立即把一个函数添加到微队列
Promise.resolve().then(函数)
 
浏览器还有很多其他的队列,由于和我们开发关系不大,不作考虑
面试题:阐述一下JS的事件循环
参考答案:
事件循环又叫做消息循环,是浏览器渲染主线程的工作方式。
在Chrome的源码中,它开启一个不会结束的for循环,每次循环从消息队列中取出第一个任务执行,而其
他线程只需要在合适的时候将任务加入到队列未尾即可。
过去把消息队列简单分为宏队列和微队列,这种说法目前已无法满足复杂的浏览器环境,取而代之的是一种更
加灵活多变的处理方式。
根据W3C官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列,不同的任务可以属于不同的
队列。不同任务队列有不同的优先级,在一次事件循环中,由浏览器自行决定取哪一个队列的任务。但浏览器
必须有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。
面试题:JS中的计时器能做到精确计时吗?为什么?
参考答案:
不行,因为:
1.计算机硬件没有原子钟,无法做到精确计时ǐ
2.操作系统的计时函数本身就有少量偏差,由于JS的计时器最终调用的是操作系统的函数,也就携带了这些偏差
3.按照W3C的标准,浏览器实现计时器时,如果嵌套层级超过5层,则会带有4毫秒的最少时间,这样在计时时间少于4毫秒时又带来了偏差
4.受事件循环的影响,计时器的回调函数只能在主线程空闲时运行,因此又带来了偏差
④:js优先级案例
1.案例1
setTimeout(function (){console.log(1)
}, 0)console.log(2)
 

2.案例2
// 死循环指定的时间
function delay(duration){var start = Date.now();while(Date.now() - start < duration){  }
}setTimeout(function (){console.log(1)
},0)delay(1000)console.log(2)
 

3.案例3
setTimeout(function (){console.log(1)
},0)// 将改任务放到微队列中(微队列:优先级最高)
Promise.resolve().then(function(){console.log(3)
})console.log(2)
 

相关文章:
01_原理-事件循环
01_原理-事件循环 文章目录 01_原理-事件循环一、浏览器的进程模型①:何为进程?②:何为线程?③:浏览器有哪些进程和线程? 二、渲染主线程是如何工作的?三、若干解释①:何为异步&…...
Redis的性能,哨兵模式,集群,
Redis的性能管理; redis的数据保存在内存中 redis-cli info memory redis内存使用info memory命令参数解析 used_memory:236026888 由 Redis 分配器分配的内存总量,包含了redis进程内部的开销和数据占用的内存,以字节(byte)…...
如何选择共模噪声滤波器
在当前电子产品中,绝大多数的高速信号都使用地差分对结构。 差分结构有一个好处就是可以降低外界对信号的干扰,但是由于设计的原因,在传输结构上还会受到共模噪声的影响。 共模噪声滤波器就可以用于抑制不必要的共模噪声,而不会对…...
Python与设计模式--模板模式
23种计模式之 前言 (5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、(11)策略模式、责任链模式、命令模式、中介者模…...
LoadRunner自动化测试工具的应用
目录 第一部分:Loadrunner的简介 1.1 安装注意事项 1.2 协议的选择或者 VUSER 类型的选取 1.3 LR 的基本原理 1.4 测试脚本录制/分配所遵循的几个原则 第二部分:录制脚本 2.1 录制脚本前需要理解的几个基本概念 2.1.1 事务(Transaction) 2.1.2 集合点(Rendezvous) 2.1…...
工厂模式是一种创建对象的设计模式,使用工厂类来创建对象,而不是直接使用 new 关键字来创建对象。
文章目录 示例代码virtual std::string Operation() const = 0;如何理解std::string Operation() const override {这句如何理解?Factory 类包含一个静态方法 CreateProduct,它根据传入的类型参数来创建并返回具体的产品实例。这句话理解?std::unique_ptr<Product> pr…...
NET MVC中使用Element-Plus框架编写组件
一、目的 在NET MVC中使用Element-Plus编写可重复使用的组件。 二、准备工作 2.1 NET MVC项目 2.2 MVC项目中使用Element-Plus框架。不熟悉的可以参考此文章: NET MVC中如何使用Element-Plus-CSDN博客 三、组件编写 3.1、新建一个MVC的部分视图页面ÿ…...
在线文库系统 转码功能源代码展示 支持文档在线预览查阅功能
1、支持 pdf,doc,docx,ppt,pptx,txt,xlsx,xls,csv,zip,epub,ai,psd 格式的文件 2、文库系统的上传界面,用户可以进行上传自己的文件,然后自定义文档售价,来赚取金额。 3、文库系统的部分代码披露: <template><div clas…...
Linux /etc/shadow密码生成操作示例
一. 前言 之前学习过Linux文件系统下/etc/shadow里面保存着各个用户名的密码,并且密码是通过MD5算法加盐的方式生成的。但是一直没有自己真正动手生成过,今天,就来自己动手写代码生成下。 二. 代码验证/etc/shadow中密码 1. 通过passwd命令生…...
seata集成springboot的一些错误小计
1 seata依赖没找到 dependencies.dependency.version for com.alibaba.cloud:spring-cloud-starter-alibaba-seata:jar is missing. line 126, column 21错误原因:未指定具体的seata版本 解决 <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-st…...
springmvc(基础学习整合)
SpringMVC是Spring框架提供的构建Web应用程序的全功能MVC模块。 在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。 springMVC基本介绍: http://t.csdnimg.cn/TOzw9 MVC是一种设计思想,将一个应…...
采集软件大全-全网免费的采集软件大全
采集软件大揭秘:从排名到任意网站采集的全方位解读 在数字时代,信息是黄金,而采集软件就是那把能够淘金的工具。无论是市场调研、竞品分析还是SEO优化,采集软件都扮演着不可或缺的角色。在这个领域里,有许多选择&…...
世微AP5125 DC-DC降压恒流 LED车灯电源驱动IC SOT23-6
产品描述 AP5125 是一款外围电路简单的 Buck 型平均电流检测模式的 LED 恒流驱动器,适用于 8-100V 电压范围的非隔离式大功率恒流 LED 驱动领域。芯片采用固定频率 140kHz 的 PWM 工作模式, 利用平均电流检测模式,因此具有优异的负载调整 率…...
STC15-串口通信打印输出数据printf函数与sprintf函数
STC15-串口通信打印输出数据printf函数与sprintf函数 1.打印输出数据有二种printf函数与sprintf函数,不同之处有:(1)函数的声明不同(2)函数的功能不同(3)用法举例 该问题引用百度知道…...
Android 11.0 默认开启USB调试功能
Android 11.0 默认开启USB调试功能 近来收到项目反馈需求想要默认开启USB调试功能,默认开启USB调试功能主要是在UsbDebuggingActivity.java文件中实现,具体修改参照如下: /vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/and…...
单片机AVR单片机病房控制系统设计+源程序
一、系统方案 设计一个可容8张床位的病房呼叫系统。要求每个床位都有一个按钮,当患者需要呼叫护士时,按下按钮,此时护士值班室内的呼叫系统板上显示该患者的床位号,并蜂鸣器报警。当护士按下“响应”键时,结束当前呼叫…...
C语言——多种方式打印出1000之内的所有的“水仙花数”
所谓水仙花数,是指一个3位数,其各位数字立方和等于该数本身。水仙花数是指一个三位数,它的每个位上的数字的立方和等于它本身。例如,153是一个水仙花数,因为1^3 5^3 3^3 153。 方法一 #define _CRT_SECURE_NO_WARNINGS 1#include <std…...
.net 8 发布了,试下微软最近强推的MAUI
先看下实现的效果: 下面发下XAML文件: <?xml version"1.0" encoding"utf-8" ?> <ContentPage xmlns"http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x"http://schemas.microsoft.com/winfx/2009/…...
【产品经理】AI在SaaS产品中的应用及挑战
随着ChatGPT大模型在全球的爆火,AI迅速在各个行业内,助力于各行业的效率提升。而SaaS领域,AI同样也大有可为。 AI(人工智能,Artificial Intelligence的缩写)近一年来一直处于舆论风口,随着ChatG…...
Python实现一箭穿心
文章目录 🎄效果🏳️🌈Turtle模块🌹代码🌺代码讲解 🎄效果 🏳️🌈Turtle模块 Turtle是一个绘图工具,是Python标准库中的一个模块。它提供了一种简单而直观的方式来创…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
从实验室到产业:IndexTTS 在六大核心场景的落地实践
一、内容创作:重构数字内容生产范式 在短视频创作领域,IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色,生成的 “各位吴彦祖们大家好” 语音相似度达 97%,单条视频播放量突破百万…...
【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战
🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...
C#中用于控制自定义特性(Attribute)
我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)] 这个 C# 属性。 在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。Attr…...
多模态学习路线(2)——DL基础系列
目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization(RMSNorm) 二、激活函数 1. Sigmoid激活函数(二分类&…...
