JavaScript 运行机制

文章目录

    • JavaScript 运行机制
    • 目标
    • 知识要点
      • 一、进程与线程
        • 1.1 概念
        • 1.2 区别
        • 1.3 多进程与多线程
        • 1.4 JS 为什么是单线程
        • 1.5 浏览器
          • 1.5.1 浏览器包含哪些进程
          • 1.5.2 为什么浏览器要多进程
          • 1.5.3 渲染进程
            • 1.5.3.1 GUI 渲染线程
            • 1.5.3.2 JS 引擎线程
            • 1.5.3.3 事件触发线程
            • 1.5.3.4 定时触发器线程
            • 1.5.3.5 异步HTTP请求线程
      • 二、事件循环(Event Loop)基础
      • 三、宏任务与微任务
        • 3.1 宏任务(macrotask)
        • 3.2 微任务(microtask)
      • 四、完整的事件循环(Event Loop)
      • 五、Promise & async/await
        • 5.1 Promise
        • 5.2 async/await

JavaScript 运行机制

原文链接:JavaScript运行机制

目标

1.了解进程与线程的基础概念,明确在浏览器中的进程与线程机制;

2.了解浏览器与Node中的事件循环;

知识要点

一、进程与线程

1.1 概念

进程:CPU资源分配的最小单位。——可以独立运行且拥有自己的资源空间的任务程序。(包括运行中的程序和程序中所用到的内存和系统资源)。
eg:每打开一个软件就会产生一个进程,浏览器中每开一个Tab页也会产生一个进程。进程之间相互独立。

线程:CPU调度的最小单位。——建立在进程基础上的一次程序运行单位。一个进程可以有多个线程。一个程序中可以同时运行多个不同的线程来执行不同的任务。

1.2 区别

进程包含了线程,一个进程可以对应多个线程。线程相当于是进程中的不同执行路线。

调度和切换:线程上下文切换比进程上下文切换要快得多。

1.3 多进程与多线程
  • 多进程:允许同一计算机系统中同时运行两个或两个以上的进程。比如在打开网易云听歌的同时还可以打开编辑器敲代码,而这两个进程之间不会相互干扰。
  • 多线程:指一个程序中包含多个执行流来执行不同的任务,而这多个不同的执行流是并行的。
1.4 JS 为什么是单线程

JS主要用途是与用户互动,以及操作DOM。

如果JS是多进程的话,那么它可以同时在某个DOM节点上添加内容,又可以删除这个节点,从而导致浏览器不知该以哪个为准。

1.5 浏览器
1.5.1 浏览器包含哪些进程

浏览器包含以下进程:

  • Browser进程
  • 第三方插件进程
  • GPU进程(Graphics Processing User)
  • 渲染进程
1.5.2 为什么浏览器要多进程

若浏览器是单进程,那么如果某个Tab页崩溃了,则会导致整个浏览器瘫痪,同理,如果插件崩溃了则会影响整个浏览器,这样体验感非常差。

1.5.3 渲染进程

页面渲染,JS的执行,事件的循环,都在渲染进程中执行,所以需要重点了解渲染进程。

渲染进程是多线程的,以下是一些常用较为主要的线程:

1.5.3.1 GUI 渲染线程
  • 负责渲染浏览器界面,解析html,css,构建DOM树和RenderObject树,布局和绘制等

1.解析html代码转化为浏览器认识的节点,生成DOM树,

2.解析CSS,生成CSSOM(CSS规则树)

3.把DOM Tree 和 CSSOM结合,生成Rendering Tree(渲染树)

  • 当修改元素的颜色或背景色时,页面会重绘
  • 当修改元素尺寸时,页面会回流
  • 当页面需要重绘和回流时,执行GUI线程,绘制页面
  • 回流比重绘成本高
  • GUI渲染线程和JS引擎线程是互斥的

1.当JS引擎线程执行时,GUI渲染线程会被挂起

2.GUI渲染线程会被保存在一个队列中等到JS引擎空闲时立即被执行

1.5.3.2 JS 引擎线程
  • JS 引擎线程就是 JS 内核,负责处理 Javascript 脚本程序
  • JS 引擎线程负责解析 JS 脚本,运行代码
  • JS 引擎线程一直等待队列中的任务到来,然后执行
  • JS 引擎线程和 GUI 渲染线程是互斥的,js 引擎线程会阻塞 GUI 渲染线程
1.5.3.3 事件触发线程
  • 事件触发线程管理着一个事件队列,用来控制事件循环
  • 当js执行碰到事件绑定或一些异步操作时,会交由事件触发线程将对应的事件添加到对应的线程中(如定时器事件会添加到定时触发器线程中),等异步事件有了结果,便把结果添加到事件队列中,等待js引擎线程空闲时来处理。
  • 当对应的事件符合触发条件触发时,该线程会将事件添加到事件队列的队尾,等待JS引擎处理
  • 因为JS是单线程,所以待处理队列中的事件都得排队等JS引擎处理
1.5.3.4 定时触发器线程
  • 当JS代码执行中遇到定时任务(如setTimeout、setInterval),会将该定时器任务交由定时触发线程处理,然后等计时完毕,便将事件添加至事件触发线程的事件队列中,等待JS引擎空闲后处理
1.5.3.5 异步HTTP请求线程
  • 当JS代码执行过程中,若遇到http异步请求,则将该异步请求事件交由异步http请求线程,等异步事件响应成功后(即状态码变更),再将事件添加至事件触发线程的事件队列中等待JS引擎空闲后处理

二、事件循环(Event Loop)基础

  • 1.在js代码执行过程中,从上至下逐行解析,遇到同步代码可直接执行,
  • 2.若遇到定时器任务或异步请求,则将事件添加至事件触发器的事件队列末尾(算作下一次事件循环)
  • 3.当同步任务全部执行完毕,则不断问询事件队列中是否有回调事件,
  • 4.若有,则将事件回调放入执行栈中执行,然后再接着回到步骤1

img

三、宏任务与微任务

3.1 宏任务(macrotask)

我们可以把每次执行栈中执行的代码当作是一个宏任务(包括从事件队列中取出一个事件回调放到执行栈中执行),每一个宏任务都会从头至尾执行,不会执行其他。宏任务中的代码都是同步的。

由于JS引擎线程和GUI渲染线程互斥,所以浏览器为了宏任务和DOM任务有序的进行,会在每一个宏任务执行完毕后,都会在下一个宏任务执行前,GUI渲染线程开始工作,对页面进行渲染。

常见的宏任务有以下几种:

  • 主代码块
  • setInterval
  • setTimeout
  • setImmediate()-Node
  • requestAnimationFrame() -浏览器
3.2 微任务(microtask)

微任务为在当前宏任务执行后立即执行的任务。

当一个宏任务执行完,会在渲染前,将执行期间所产生的所有微任务都执行完:

*任务执行过程:宏任务->微任务->GUI渲染->宏任务->微任务->GUI渲染->xxx*

以下形式的代码为微任务

  • process.nextTick()-Node
  • Promise.then()
  • catch
  • finally
  • Object.observe
  • MutationObserver

img

四、完整的事件循环(Event Loop)

img

五、Promise & async/await

5.1 Promise

new Promise(()=>{}).then()中,前面的new Promise(()=>{})是一个构造函数,这是一个同步任务,后面的.then()才是一个异步微任务:

new Promise((resolve)=> {
    console.log(1);
    resolve();
}).then(()=> {
    console.log(2)
})
cosole.log(3)
// 1 3 2
5.2 async/await

async/await本质上还是基于Promise的一些封装,而Promise是属于微任务的一种

所以在使用await关键字的效果与Promise.then效果类似,await以前的代码,相当于new Promise的同步代码,await以后的代码,相当于Promise.then的异步

setTimeout(()=> console.log(4))  // 进入下一次事件循环

async function test(){
  console.log(1)
  await Promise.resolve()
  console.log(2)
}
test()

console.log(3)
// 1 3 2 4

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows权限维持方法论

Windows权限维持方法论 1.注册表自启动2.组策略设置脚本启动3.计划任务4.服务自启动5.dll劫持6.直接上远程控制木马 1.注册表自启动 通过修改注册表自启动键值,添加一个木马程序路径,实现开机自启动 常用的注册表启动键: # Run键 HKEY_CU…

echarts移动markline(拖拽单条markline)

echarts移动markline(拖拽单条markline) 效果 问题由来: 图表中需要一个移动的标线,辅助观察图表; 想法: 意思是在原来点或者原来标线上新增一个图层,拖动图层动态绘制新的点或者新的标线; 参考…

【C++初阶】STL详解(五)List的介绍与使用

本专栏内容为:C学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C 🚚代码仓库:小小unicorn的代码仓库&…

万字解析:十大排序(直接插入排序+希尔排序+选择排序+堆排序+冒泡排序+快速排序+归并排序+计数排序+基数排序+桶排序)

文章目录 十大排序排序算法复杂度及稳定性分析一、 排序的概念1.排序:2.稳定性:3.内部排序:4.外部排序: 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四…

这是大学生就业网站最基础的布局。

<!DOCTYPE html> <html> <head> <title>大学生就业网站</title> <style> /* Reset default margin and padding */ *, *::before, *::after { margin: 0; padding: 0; box-s…

算法刷题-动态规划2

算法刷题-动态规划2 珠宝的最高价值下降路径最小和 珠宝的最高价值 题目 大佬思路 多开一行使得代码更加的简洁 移动到右侧和下侧 dp[ i ][ j ]有两种情况&#xff1a; 第一种是从上面来的礼物最大价值&#xff1a;dp[ i ][ j ] dp[ i - 1 ][ j ] g[ i ][ j ] 第二种是从左…

FPGA设计时序约束九、others类约束之Group Path

目录 一、序言 二、Group Path 2.1 基本概念 2.2 设置界面 2.3 命令语法 2.4 命令示例 三、工程示例 四、参考文件 一、序言 在Vivado的时序约束窗口中&#xff0c;存在一类特殊的约束&#xff0c;划分在others目录下&#xff0c;可用于设置忽略或修改默认的时序路径分…

如何判断客户对你是不是真的满意

我们平时生活中打个滴滴、叫个外卖&#xff0c;都会让做星级评价&#xff0c;就算去银行办业务&#xff0c;也会让按个按钮&#xff0c;对窗口的服务做个评价…… 再问一个问题&#xff1a;客户满意了&#xff0c;您的生意就一定好吗&#xff1f; 一、满意度&#xff1a;质量监…

EDIFACT学习手册

EDIFACT 又名 UN/EDIFACT&#xff08;全称为 United Nations/Electronic Data Interchange For Administration, Commerce and Transport&#xff09;&#xff0c;是由联合国主导开发制定的国际通用 EDI 标准。EDI术语中的EDIFACT是指 EDIFACT 报文标准&#xff0c;本视频将为大…

python接口自动化封装导出excel方法和读写excel数据

一、首先需要思考&#xff0c;我们在页面导出excel&#xff0c;用python导出如何写入文件的 封装前需要确认python导出excel接口返回的是一个什么样的数据类型 如下&#xff1a;我们先看下不对返回结果做处理&#xff0c;直接接收数据类型是一个对象&#xff0c;无法获取返回…

Postman API Enterprise 10.18.1 Crack

适合您企业的 Postman API 平台 掌控您的 API 环境。构建更好的 API。加快产品开发。 无论您处于 API 之旅的哪个阶段&#xff0c;Postman 都会为您提供帮助 想让您团队的 API 更容易被发现吗&#xff1f;希望减少开发和质量检查之间的滞后时间&#xff1f;想要更快地让新开发…

2023年09月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 点击绿旗,运行程序后,舞台上的图形是?( ) A:画笔粗细为4的三角形 B:画笔粗细为5的六边形 C:画笔粗细为4的六角形 D:画笔粗细为5的三角形 答案:D 第2题 如下图所示,从所给…

AI一点通:卷积神经网络的输出节点大小如何计算?全连接层必要输入大小如何设置

在使用卷积网络&#xff08;CNN&#xff09;时&#xff0c;一个步骤是计算经过卷积和池化步骤后的输出大小&#xff0c;以便我们可以将输出连接到一个完全收集的线性层。 以Pytorch中的一维CNN为例&#xff0c; self.conv1 nn.Conv1d(in_channels1, out_channels64, kernel_s…

地图导航测试用例,你get了吗?

地图导航是我们经常使用的工具&#xff0c;能帮助我们指引前进的方向。 接下来&#xff0c;会从功能测试、UI测试、兼容测试、安全测试、网络测试、性能测试、易用性测试、文档和国际化语言测试8个方面来编写地图导航测试用例。 一 功能测试 输入起点和终点&#xff0c;验证…

你了解Postman 变量吗?

变量是在Postman工具中使用的一种特殊功能&#xff0c;用于存储和管理动态数据。它们可以用于在请求的不同部分、环境或集合之间共享和重复使用值。 Postman变量有以下几种类型&#xff1a; 1、环境变量&#xff08;Environment Variables&#xff09;: 环境变量是在Postman…

【Linux】权限的理解和使用

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

使用Java Servlet生成动态二维码

文章目录 引入ZXing库创建QRCodeServlet部署到Servlet容器拓展功能1. 动态生成二维码内容2. 调整二维码尺寸3. 错误修正级别4. 日志输出 结语 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…

【Python大数据笔记_day11_Hadoop进阶之MR和YARNZooKeeper】

MR 单词统计流程 已知文件内容: hadoop hive hadoop spark hive flink hive linux hive mysql ​ input结果: k1(行偏移量) v1(每行文本内容)0 hadoop hive hadoop spark hive 30 flink hive linux hive mysql map结果:k2(split切割后的单词) v2(拼接…

Windows配置Anaconda环境

1、下载Anaconda 2、安装Anaconda 2.1、系统环境变量 注&#xff1a; 将Anaconda添加到系统环境变量中&#xff0c;此处建议选中&#xff0c;可以省去好多麻烦 2.2、手动配置环境变量 系统—高级系统设置—环境变量—Path—新建&#xff1b;将下面的路径添加到环境变量中…

智能安全帽作业记录仪赋能智慧工地人脸识别劳务实名制

需求背景 建筑工地是一个安全事故多发的场所。目前&#xff0c;工程建设规模不断扩大&#xff0c;工艺流程纷繁复杂&#xff0c;如何完善现场施工现场管理&#xff0c;控制事故发生频率&#xff0c;保障文明施工一直是施工企业、政府管理部门关注的焦点。尤其随着社会的不断进…