JS引擎中的线程,事件循环,上下文

线程,JS,事件,循环 · 浏览次数 : 160

小编点评

**JS执行上下文** JS执行上下文是JS代码执行的环境,JS代码的执行一定要在其执行上下文中。 **JS执行上下文的基本结构** * **ExecutionContext**: 包含了变量对象、作用域链和this对象。 * **VO**: 变量对象,保存了函数运行过程中所创建的变量。 * **scopeChain**: 作用域链,记录了函数调用之间的关系。 * **this**: 指向函数的执行上下文中的this对象。 **JS执行上下文的生命周期** 1. **创建**: 当JS代码被执行时,创建一个新的ExecutionContext对象。 2. **初始化**: 存储了函数运行所需的所有变量和环境。 3. **执行**: 运行函数的代码。 4. **清理**: 当函数执行完毕时,清理ExecutionContext、VO、scopeChain和this对象。 **JS执行上下文的功能** * 存储函数运行所需的所有变量和环境。 * 允许函数在执行过程中访问其他函数的局部变量。 * 提供了一种隔离执行机制,防止函数间相互影响。 **JS执行上下文的使用场景** * 在函数中访问其他函数的局部变量。 * 在函数中执行耗时操作。 * 限制函数间相互调用。

正文

 
线程
浏览器中有哪些进程呢?
1.浏览器进程:浏览器的主进程,负责浏览器的界面界面显示,与用户交互,网址栏输入、前进、后退,以及页面的创建和销毁。
2.渲染进程(浏览器内核):默认一个tab页面一个渲染进程,主要的作用为页面渲染,脚本执行,事件处理等。
3.GPU进程:用于3D绘制等,将开启了3D绘制的元素的渲染由CPU转向GPU,也就是开启GPU加速。
4.网络进程:主要负责页面的网络资源加载。
5.插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。
6.音频进程:浏览器音频管理。
 
浏览器内核就是在渲染进程中,里面包含了多个引擎,它们拥有各自的线程。
GUI渲染线程
负责解析html, css。构建DOM树和RenderObject树。布局和绘制。
当页面元素中的某个dom节点有变化,需要绘制时,此线程就会执行。

JS引擎线程
它里面有个event loop和一个事件队列。这2者是JS引擎的核心基础。
拥有异步处理能力,JS引擎是单线程但可以实现异步并发处理事件,实现异步的基础是依靠上面的event loop和事件队列。H5的 Web Worker 标准规定,允许 JavaScript 脚本创建多个线程,但是子线程完全受主线程控制,且不得操作 DOM。所以,这个新标准并没有改变 JavaScript 单线程的本质。
它与GUI渲染线程互斥,用于处理页面交互和DOM更新,所以JS引擎线程和GUI渲染线程在处理任务时必须保证按顺序串行执行,一个执行另一个就要等待,这样才能保证每次页面渲染,更新都是确定的,不存在冲突。所以如果js处理的事件耗时,页面就会出现卡顿。
JS引擎主要负责处理JS脚本的词法分析,语法分拆,生成语法树,代码执行。内存管理,垃圾回收。

事件触发线程
监控各种事件的发生,比如用户的交互事件、页面DOM渲染完成事件等。当这些事件发生时,事件触发线程会将回调事件从定时器触发线程或者异步HTTP请求线程它们的事件队列中读取出来,放置到JS引擎的事件队列中,等待JavaScript引擎的执行。
辅助JS引擎线程管理事件队列,它和JS引擎线程是平级的关系。它的管理事件队列体现在将要处理的事件从其他线程队列中取出放到JS引擎的事件队列中。

定时器触发线程
用于专门做定时器计数用的,如果其他线程做这件事,可能会因为执行耗时任务而错过按时触发。
触发时机是当js引擎执行到setTimeOut, setInternal时,就会调用对应的webAPI,这些系统API内部都是将任务放置到定时器触发线程中进行处理,在线程中会把定时器事件以key:value的形式保存在event table中 方法名:回调函数 ,当回调时间到时,就将回调函数放置在自己的事件队列中,并发通知到事件触发线程,让事件触发线程将
事件放置到JS引擎的事件队列中。

异步HTTP请求线程
主要用于检测网络状态变化,如果检测到网络成功回调,则会把保存在自己event table中的回调事件放置到当前线程自己的事件队列中,然后通知,则会通知时间触发线程把处理回调函数放置到事件队列中。,并发通知到事件触发线程,让事件触发线程将
事件放置到JS引擎的事件队列中。
触发时机是当js引擎执行到ajax请求时,则会调用webAPI提供的接口,接口内部就会切换到异步HTTP请求线程中做网络事件的处理。
 
事件循环
 
事件循环主要解决了哪些问题?
1.避免耗时任务阻塞流程
html页面的加载是串行的,渲染进程解析HTML页面文件,碰到页面标签和css时,交给GUI渲染线程处理,碰到js标签时,则停止GUI渲染线程开始让js引擎处理js任务,如果要等耗时任务执行完再执行下面的任务,则卡主了页面。
2.增加了CPU执行效率
当JS引擎执行时碰到setTimeOut定时器事件,ajax网络事件时,都会调用webAPI让系统在专门的子线程进行处理,等到了回到时间,再把回调任务添加到js引擎的任务队列中,实现了耗时任务的同步执行。串行回调,增加了执行效率。

JS引擎的代码执行流程
1.JS引擎开始执行代码。
2.根据代码中的async,sync 同步、异步标识确定走同步流程还是异步流程。
3.同步流程是运行在JS引擎线程的,异步流程则是使用单独的线程进行处理,等处理完了将事件回调放置到JS引擎的事件队列中,让JS引擎进行执行。
4.当JS引擎执行完任务后会检查其任务队列中是否还有待处理的任务,如果有就继续出来,如果没有就停止等待。
js引擎存在一个monitoring process进程,它会持续不断的检查主线程执行栈是否为空,一旦检测到有任务就通知JS引擎取出任务执行。
任务的执行是按照任务进入队列的顺序进行的。任务的执行时间是受上一个任务的执行时长决定的,就像setTimeOut,方法里设置的是2秒后将回调放入js引擎的事件队列,但是任务的具体执行时间是不能确定的。

 

宏任务与微任务
setTimeOut, setInterval, async这样的是宏任务
progress.nextTick, Promise这样的是微任务,微任务是在执行宏任务的时候产生的,它存在全局上下文中。
宏任务与微任务的执行顺序是:宏任务 -> 微任务 -> 宏任务 -> 微任务 -> 空。
先执行宏任务,执行结束后。查看微任务队列中是否有微任务,有的话就执行,如果在执行微任务的过程中又产生了微任务,那么这个新的微任务会直接添加到当前执行的微任务队列。直到微任务队列中的任务都执行完才会开启下一轮宏任务->微任务循环。

 

JS执行上下文
 
JS执行上下文是JS代码执行的环境,JS代码的执行一定要在其执行上下文中。
全局执行上下文:浏览器中的全局上下文就是window, window是一个对象,全局上下文中的this指向的就是window。
函数执行上下文:每次函数的调用都会产生一个函数上下文,函数上下文内容包括:参数,局部变量的栈空间,堆空间。
上下文的生命周期如下:

 

上下文是一个对象,里面包含了变量对象VO,作用域链scopeChain,this对象。其基本结构如下:
ExecutionContext={
  scopeChain:{},
  VO:{},
  this:{}
}
全局上下文变量对象
globalEC={
   VO:window,
   scopeChain:{},
   this:window
}
函数上下文变量对象
function a(a,b){}
a(1,2)
innerTestEC={
  VO={
    arguments:{0:1,1:2,length:2}
    a:undefined,
    b:undefined
    },// 变量对象
  scopeChain:[VO(innerTest),VO(test),VO(global)],//作用域链
  this:{}
}

 


参考文章:
https://juejin.cn/post/6844903512845860872
https://zhuanlan.zhihu.com/p/492563097



与JS引擎中的线程,事件循环,上下文相似的内容:

JS引擎中的线程,事件循环,上下文

线程 浏览器中有哪些进程呢? 1.浏览器进程:浏览器的主进程,负责浏览器的界面界面显示,与用户交互,网址栏输入、前进、后退,以及页面的创建和销毁。 2.渲染进程(浏览器内核):默认一个tab页面一个渲染进程,主要的作用为页面渲染,脚本执行,事件处理等。 3.GPU进程:用于3D绘制等,将开启了3D绘

第135篇:Three.js基础入门

好家伙,这东西太帅了,我要学会 先放张帅图(都是用three.js做出来的,这我学习动力直接拉满) 还有另外一个 Junni is... 帧数太高,录不了 开始学习 官方文档 1.Three.js是什么? Three.js是一款运行在浏览器中的 3D 引擎(基于WebGL的API的封装),你可以用它

浅析Vite本地构建原理

前言 随着Vue3的逐渐普及以及Vite的逐渐成熟,我们有必要来了解一下关于vite的本地构建原理。 对于webpack打包的核心流程是通过分析JS文件中引用关系,通过递归得到整个项目的依赖关系,并且对于非JS类型的资源,通过调用对应的loader将其打包编译生成JS 代码,最后再启动开发服务器。

第一百一十一篇:基本引用类型Date

好家伙,本篇为《JS高级程序设计》第五章的学习笔记 1.基本引用类型 引用值(或者对象)是某个特定引用类型的实例,在ECMAScript中,引用类型是把数据和功能组织到一起的结构,(像极了“类”) 经常被人错误的称作“类”。 虽然从技术上讲JavaScript是一门面向对象语言,但是ECMAScri

如何使用zx编写shell脚本

前言 在这篇文章中,我们将学习谷歌的zx库提供了什么,以及我们如何使用它来用Node.js编写shell脚本。然后,我们将学习如何通过构建一个命令行工具来使用zx的功能,帮助我们为新的Node.js项目引导配置。 编写Shell脚本的问题 创建一个由Bash或者zsh执行的shell脚本,是自动化重

Web3开发者技术选型:前端视角(next.js)

引言 在现代Web开发的世界中,Web3技术的兴起为前端开发者开辟了新的可能性。Web3技术主要指的是建立在区块链基础上的分布式网络,使用户能够通过智能合约和去中心化应用(DApps)直接交互,而无需传统的中介机构。为了有效地开发Web3应用,前端开发者需要掌握一些关键的技术和工具,其中Next.j

如何使用Node.js、TypeScript和Express实现RESTful API服务

Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Express是一个保持最小规模的灵活的 Node.js Web应用程序开发框架,为Web和移动应用程序提供一组强大的功能。使用Node

初探富文本之编辑器引擎

初探富文本之编辑器引擎 在前文中我们介绍了富文本的基础概念,以及富文本的基本发展历程,那么在本文中将会介绍当前主流开源的富文本编辑器引擎。当前使用最广泛的富文本编辑器是L1的富文本编辑器,其能满足绝大部份使用场景,由此也诞生了非常多优秀的开源富文本引擎,这其中有仅提供引擎的编辑器例如Slate.js

如何基于three.js(webgl)引擎架构,研发一套通过配置就能自动生成的3D机房系统

自动化3D机房、微模块、3D机房、3D数据中心、科技感数据中心、三维机房、3d建筑,3d消防,消防演习模拟,3d库房,3d档案室,3d密集架,webGL,threejs,3d机房,bim管理系统

什么是 x10 开发工具?「GitHub 热点速览」

都听过 10x 工程师,一个人顶得过十个人。但是并不是每个人都是 10x 工程师,但是有些效率工具可能让你变成 2x、3x 的工程师。比如,这周火爆的 3D 游戏引擎 FlaxEngine 有着强大的脚本和即开即用的功能特性,极简只有 2.3 kb 的 JS 工具库 nuejs,还有网页版的 whi...