js中的事件循环

浏览器进程模型

在理解什么叫事件循环前,我们需要先知道浏览器的进程模型
现代浏览器的功能极度复杂,为了能确保各个部分独立运行互不影响,浏览器会在启动之时开启多个进程,具体而言可以分为以下三种

  1. 浏览器进程
    负责浏览器的用户交互,子进程管理,浏览器页面显示等等,浏览器进程是最先被启动的进程,将由它来启动并维护其他进程
  2. 网络进程
    负责浏览器的网络通信,加载网络资源,会在内部开启多个线程来维护不同的网络任务
  3. 渲染进程
    渲染进程不同于其他进程,它一次只能开启一个线程,这个线程也被称为渲染主线程,将由它负责渲染页面,执行js等等

进程模型

默认情况下,现代浏览器都是开启一个页面则开启一个渲染进程,具体可以通过浏览器的任务管理器来查看

管理器

渲染主线程

渲染主线程可以说是浏览器中最繁忙的线程,因为各种各样的原因导致渲染进程一次只能开启一个渲染主进程,所以主线程将负责包括但不限于以下内容

  1. 解析HTML
  2. 解析CSS
  3. 执行JS代码
  4. 处理图层

可以看到渲染主线程的任务多且杂,但渲染主线程只有一个,一次只能执行一个任务,那任务与任务之间又如何调度

渲染主线程的解决方案是将任务排队

消息队列

渲染主线程会维护消息队列,所有任务都需要按照先来后到的顺序放入消息队列中,渲染主线程则会依次取出 消息队列中的任务执行,具体有以下步骤

  1. 最开始渲染主线程会开启一个死循环
  2. 每一次循环渲染主线程都会检测消息队列中是否有任务,如果有就取出执行,没有就进入休眠状态
  3. 其他线程可以随时向消息队列中添加任务,如果此时渲染主线程处于休眠状态则会被唤醒

基于这样一个循环,我们的渲染主线程就能有条不紊的执行下去了

在这里插入图片描述

异步

到现在为止一切似乎都没什么问题,任务在消息队列的调度下能有序执行,最大的困难便解决了,但任务不全都是同步执行,有些任务浏览器遇到了之后并不立刻执行,如setTimeOutsetIntervalPromise等等,如果直接将其当做同步任务执行的话就会导致页面阻塞

阻塞
为了保证用户的使用体验,使页面不被卡死,因此浏览器采用异步的方式来解决这个问题,具体步骤如下

  1. 当渲染主线程遇到异步任务时会通知对应的线程,当前任务结束,从消息队列取出任务继续执行
  2. 其他线程开始监控,待任务到达触发时机就会将任务的回调函数包装成任务放入消息队列中
  3. 渲染主线程会自始至终从消息队列中取出任务执行

异步任务处理
当然,所有异步任务不可能都由一个线程处理,不同的异步任务会有对应的线程接管

浏览器通过使用异步的形式来使渲染主线程不会出现阻塞

由此我们能得到两个结论

单线程是异步产生的原因
事件循环是异步的实现方式

任务优先级

到了这里,似乎事件循环我们已经了解的差不多了,但还有一些疑问我们仍未解决,任务与任务之间有优先级的区别吗
事实上,任务与任务之间并没有优先级的区别,都是先进先出,但消息队列与消息队列间有着不同的优先级
消息队列向来都不只有一个,具体可以分为宏队列微队列
然而随着现代浏览器复杂度的急剧提升,原有的划分方式已不满足于现在需要,所以目前的消息队列划分如下

  1. 每个任务都会有一个任务类型同一个类型的任务必须在同一个队列不同类型的任务可以在同一个队列
  2. 每个浏览器都必须拥有一个微队列微队列里的任务优先于其他队列里的任务执行
  3. 其他队列里的任务浏览器可以按照实际情况执行

在这里插入图片描述

事件循环

最后,我们再来总结一下什么是事件循环

事件循环是浏览器渲染主线程的主要工作方式,因为各种各样的原因,浏览器开辟的渲染进程只会存在一个渲染主线程,这也就决定js是一门单线程的语言,同时渲染主线程负责的任务十分繁杂,包括渲染HTML,CSS,执行JS,每秒重绘多少多少次,布局等等,为了保证所有任务都能稳定有序执行,浏览器会维护消息队列来存放任务,其他线程可以向消息队列中提交任务,渲染主线程每次都会从消息队列中取出第一个任务来执行,如果没有任务渲染主线程就会进入休眠,待消息队列中有了新的任务就会被唤醒,如果是异步任务则会交由其他线程托管,待任务需要执行时将事件的回调函数包装成任务放入消息队列中。根据W3C规定,每个任务都有一个消息类型,同一类型的任务必须要在同一个消息队列中,不同类型的任务可以在一个消息队列中,每个浏览器必须要有一个微队列,并且微队列中的任务要先于其他消息队列中的任务执行。

关于JS中能否做到精准计时

严格上来说是不能的,主要原因有以下几点

  1. 计算机内没有原子钟,无法做到精确计时
  2. js的计时也是调用系统级的函数,会有些许偏差
  3. W3C规定计时器嵌套超过4层的话从第5层开始强制计时器有5ms延时
  4. 当计时器结束,任务进入消息队列也不是立刻执行的,需要等待渲染主线程的调用,这也会有时间上的偏差

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

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

相关文章

【JavaEE初阶系列】——文件操作 IO 之 文件系统操作

目录 📝认识文件 🚩树型结构组织 和 目录 🎈绝对路径和相对路径 🚩文件类型 📝文件系统操作 🎈File 概述 🎈File类的使用 1. 绝对路径 vs 相对路径 2. 路径分隔符 3. 静态成员变量 4…

VSCode SSH 连接 Could not establish connection to “XXX“: spawn UNKNOWN.

1. 确认问题: 拉取vscode终端:快捷键 ctrl(数字1旁边那个) 输入:ssh -V 2. 解决方法 2.1 找到本地SSH 位置 默认本地路径: C:\Windows\System32\OpenSSH 2.2 找到要修改的位置 进入 ssh 插件的设置(可以通过在插…

Jenkins首次安装选择推荐插件时出现”No such plugin cloudbees-folder”解决方案

安装Jenkins成功之后,首次启动Jenkins后台管理,进入到安装插件的步骤,选择"推荐安装",继续下一步的时候出现错误提示: 出现一个错误 安装过程中出现一个错误:No such plugin:cloudb…

基于SSM的药店药品商城管理系统

介绍 本项目分为前后台,分为管理员与普通用户两种角色,管理员登录后台,普通用户登录前台; 管理员角色包含以下功能: 管理员登录,订单管理,客户管理,药品管理,类目管理等功能。用户角色包含以下功能: 用户首…

基于51单片机智能加湿器控制系统

基于51单片机智能加湿器控制系统 (仿真+程序+原理图) 功能介绍 具体功能: 1.LCD1602实时显示湿度值(湿度范围10%-95%)和湿度阈值; 2.可以通过按键设置湿度阈值范围; 3…

JAVAEE——文件IO

文章目录 文件的概念什么是文件?树型结构组织 和 目录文件路径相对路径绝对路径 文件的分类文件的权限 文件读写IO API字符流操作API 警告字节流操作APIInputStreamOutputStream 文件的概念 什么是文件? 我们先来理解一下什么是文件,那么想…

【Leetcode】top 100 图论

基础知识补充 1.图分为有向图和无向图,有权图和无权图; 2.图的表示方法:邻接矩阵适合表示稠密图,邻接表适合表示稀疏图; 邻接矩阵: 邻接表: 基础操作补充 1.邻接矩阵: class GraphAd…

2024.04.04 健身打卡第 45 天

别让别人告诉你,你成不了才,如果你有梦想的话就要去捍卫它,那些一事无成的人,想告诉你你也成不了大器,如果你有理想的话,就要去努力实现。 2024.04.04 健身打卡第 45 天

中间件复习之-RPC框架

什么是RPC框架? RPC(Remote Procedure Call):远程过程调用。当多个应用部署在多个服务器上时,由于他们不在一个内存空间上,因此需要网络来进行通信,而RPC允许它像调用本地方法一样调用远程服务。 RPC原理 服务消费方通过RPC客户…

【卷积神经网络进展】

打基础日常记录 CNN基础知识1. 感知机2. DNN 深度神经网络(全连接神经网络)DNN 与感知机的区别DNN特点,全连接神经网络DNN前向传播和反向传播 3. CNN结构【提取特征分类】4. CNN应用于文本 CNN基础知识 1. 感知机 单层感知机就是一个二分类…

实战篇01:开发环境搭建

实战篇01-开发环境搭建 一、准备数据库 执行资料中的big_event.sql脚本,准备数据库表,命令:source /root/Desktop/bigEvent/big_event.sql连接数据库,验证执行 二、创建spring boot工程 创建spring boot工程,勾选we…

【蓝桥杯】GCD与LCM

一.概述 最大公约数(GCD)和最小公倍数(Least Common Multiple,LCM) 在C中,可以使用 std::__gcd(a, b)来计算最大公约数 1.欧几里德算法/辗转相除法 int gcd(int a,int b){return b?gcd(b, a%b):a; } 2…