浏览器原理---事件循环

浏览器原理

学习浏览器原理对于我们开发是很有必要的 我们可以了解到浏览器内部工作原理对自己的代码进行优化

进程线程

首先了解进程和线程
进程就就是内存在正在进行的应用程序 在内存中独占一个内存空间 并且进程之间是隔离的 可以看到每个应用都有一个进程 占用空间内存 那这块空间内存就可以理解为进程
在这里插入图片描述
线程
线程是进程最小的执行单位 一个进程至少有一个线程 进程开启后会创建一个线程运行代码 如果程序同时执行多块代码 主线程就会启动更多线程执行代码
一个进程可以有多个线程 进程大于线程
打开浏览器之后最少开启了四个进程
1 浏览器主进程 主要显示 页面展示 用户交互 子进程管理 提供储存等等
2 渲染进程 核心任务是将html css javascript变成用户可以交互的网页
Chrome为每个tab页创建了一个渲染进程
3 网络 负责网络资源请求
4 插件进程 负责插件运行 因为插件容易崩溃

事件循环

知道了线程进程的概念 下面我们可以看一下事件循环

1 会开启一个渲染进程

执行html css js 代码 保证页签不受影响

2 浏览器内部任务是排队的

1 最开始的时候 渲染主线程的时候会开启一个无限循环
2 每次循环的时候会检查消息队列中是否有任务 有的话就取出第一个任务 取出第一个任务执行 执行完一个后进入下一次循环 如果没有则进入休眠状态
3 其他所有线程(包括其他进程的线程)可以随时向消息队列中添加任务 任务会加到消息队列的末尾 添加新任务的时候 如果主线程是休眠状态 则会继续唤醒循环拿取任务

异步

什么是异步任务 ? 代码执行无法立即处理的任务
在这里插入图片描述
如果定时器是同步的
在这里插入图片描述
则会阻塞线程 所以解决方案是 当计时结束的时候将回调函数放到消息队列的队尾

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>哈哈哈</h1><button>点击我</button><script>var h1=document.querySelector('h1')var btn=document.querySelector('button')function delay(duration){var star=Date.now();while(Date.now()-star<duration){}}btn.onclick=function(){h1.textContent="666"//3m后重新绘制delay(3000)}</script>
</body>
</html>

任务的优先级

刚刚说了任务是在线程中排队的 其中异步任务是结束的时候回调将任务放到队尾排队
任务是没有优先级的 但消息队列中优先级 同一个类型任务必须在一个任务队列 在一次事件循环中可以取出不同的队列执行任务
览器必须有个微队列 优先于其他所有任务执行
在这里插入图片描述
在这里插入图片描述
例子
同时等待一秒钟 然后执行2在执行1在这里插入图片描述
例子
先执行全局的3 然后执行微队列中的2 在执行延时队列中的1

<script>setTimeout(()=>{console.log(1);},0)Promise.resolve().then((function(){console.log(2);}))console.log(3);//3 2 1</script>

例子
先执行3 在执行2 然后继续执行微队列中的12888 在执行1

<script>setTimeout(()=>{console.log(1);},0)Promise.resolve().then((function(){console.log(2);})).then(()=>{console.log(12888);})console.log(3);//3 2 1288 1</script>

例子
执行全局的5 在执行微任务4 在执行3 将a推入微任务队列 执行1 继续将function推入微任务队列 2

<script>function a(){console.log(1);Promise.resolve().then(function(){console.log(2);})}setTimeout(()=>{console.log(3);Promise.resolve().then((a))},0)Promise.resolve().then(()=>{console.log(4);})console.log(5);//5 4  3 1 2 </script>

问答

面试题:如何理解 JS 的异步?
参考答案:
JS是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个。
而渲染主线程承担着诸多的工作,渲染页面、执行 JS 都在其中运行。
如果使用同步的方式,就极有可能导致主线程产生阻塞,从而导致消息队列中的很多其他任务无法得到执行。
这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致页面无法及时更新给用户造成本死现象。
所以浏览器采用异步的方式来避免。具体做法是当某些任务发生时,比如计时器、网络、事件监听,主线程将任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。当其他线程完成时,将事先传递的回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行。
在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行。
阐述一下 JS 的事件循环
参考答案:
事件循环又叫做消息循环,是浏览器渲染主线程的工作方式。
在 Chrome 的源码中,它开启一个不会结束的 for 循环,每次循环从消息队列中取出第一个任务执行,而其他线程只需要在合适的时候将任务加入到队列末尾即可。
过去把消息队列简单分为宏队列和微队列,这种说法目前已无法满足复杂的浏览器环境,取而代之的是一种更加灵活多变的处理方式。
根据 W3C 官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级,在一次事件循环中,由浏览器自行决定取哪一个队列的任务。但浏览器必须有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。

总结

之前是说宏任务微任务 但最新版改成了微任务队列 更加好理解了
下周还是把剩余的知识点学完准备收拾收拾写项目了

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

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

相关文章

刷题之Leetcode206题(超级详细)

206.反转链表 力扣题目链接(opens new window)https://leetcode.cn/problems/reverse-linked-list/ 题意&#xff1a;反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 思路 如果再定义一个新的链表&#xff0…

AI来了,Spring还会远吗?(Spring AI初体验)

目录 一、创建项目二、first demo1、application.properties2、ChatController3、结果 三、个人思考 一、创建项目 官方文档的Getting Started 最低要求&#xff1a;JDK17 阿里云的Server URL&#xff08;https://start.aliyun.com/&#xff09;搜不到Spring AI&#xff0c;…

dbeaver数据库语言编辑器设置jdbc驱动

打开 dbeaver 软件 数据库 -> 驱动管理器 以mysql为例 双击 MySQL -> 库 -> 添加工件 然后 打开maven组件库 官网 找到mysql驱动对应的maven工件地址 复制进去然后确认就行了 参考 大神博客

vue源码解析——diff算法/双端比对/patchFlag/最长递增子序列

虚拟dom——virtual dom&#xff0c;提供一种简单js对象去代替复杂的 dom 对象&#xff0c;从而优化 dom 操作。virtual dom 是“解决过多的操作 dom 影响性能”的一种解决方案。virtual dom 很多时候都不是最优的操作&#xff0c;但它具有普适性&#xff0c;在效率、可维护性之…

基于人脸识别的发型推荐系统代码实现

1.摘要 本文介绍了一个基于人脸识别技术的发型推荐系统的实现与分析。该系统利用Python编程语言和相关库&#xff0c;结合Face人脸识别API&#xff0c;实现了用户上传照片后的性别识别、脸型分析和发型推荐功能。首先&#xff0c;用户通过Tkinter GUI界面选择上传照片&#xff…

Niobe开发板OpenHarmony内核编程开发——定时器

本示例将演示如何在Niobe Wifi IoT开发板上使用cmsis 2.0 接口进行定时器开发 Timer API分析 osTimerNew() /// Create and Initialize a timer./// \param[in] func function pointer to callback function./// \param[in] type \ref osTimerOnce …

C++11 设计模式2. 简单工厂模式

简单工厂&#xff08;Simple Factory&#xff09;模式 我们从实际例子出发&#xff0c;来看在什么情况下&#xff0c;应用简单工厂模式。 还是以一个游戏举例 //策划&#xff1a;亡灵类怪物&#xff0c;元素类怪物&#xff0c;机械类怪物&#xff1a;都有生命值&#xff0…

自动化测试Junit

1.什么是Junit JUint是Java编程语言的单元测试框架&#xff0c;用于编写和运行可重复的自动化测试。 JUnit 促进了“先测试后编码”TDD的理念&#xff0c;强调建立测试数据的一段代码&#xff0c;可以先测试&#xff0c;然后再应用。这个方法就好比“测试一点&#xff0c;编码一…

MAT工具详解

简介 Java自带的JVisualVm可以用来分析Java堆内存&#xff0c;可以用来排查内存泄漏和内存浪费的问题&#xff0c;但是功能不是特别强大&#xff0c; MAT&#xff08;Memory Aanlysis Tool&#xff09;是一款更优的工具。 MAT功能 功能组 全局信息 直方图 按照类的数量倒序…

互联网轻量级框架整合之MyBatis配置详解

MyBatis核心配置文件mybatis-config.xml里有诸多配置项&#xff0c;但常用的就无非就如下这么多 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN" "https://mybati…

【力扣】125.验证回文串

刷题&#xff0c;过了真的好有成就感&#xff01;&#xff01;&#xff01; 题解&#xff1a; 根据题目要求&#xff0c;我们需要处理一下几个问题&#xff1a; 将大写字母转变成小写对原来的字符串进行处理&#xff0c;只要字母和数字考虑只有一个和字符串为空的情况 1、将…

整数在内存中的存储和内存操作函数

目录 整数在内存中的存储1. 整数在内存中的存储2. 大小端字节序和字节序判断2.1 什么是大小端?2.2 为什么有大小端 3. 练习3.1 请简述大端字节序和小端字节序的概念&#xff0c;设计⼀个小程序来判断当前机器的字节序。&#xff08;10分&#xff09;-百度笔试题3.2 练习23.3 练…