首页 > 其他分享 >JS引擎中的线程,事件循环,上下文

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

时间:2023-06-08 18:22:05浏览次数:44  
标签:执行 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,任务,引擎,线程,上下文,事件队列
From: https://www.cnblogs.com/zhou--fei/p/17452687.html

相关文章

  • 记录--7 个沙雕又带有陷阱的 JS 面试题
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助为了保证的可读性,本文采用意译而非直译。在JS面试中,经常会看到一些简单而又沙雕的题目,这些题目包含一些陷阱,但这些在我们规范的编码下或者业务中基本不会出现。有些面试官就是这样,不专注于制定代码的标准和规范......
  • JAVA 线程池之Callable返回结果
    JAVA线程池之Callable返回结果原文:https://www.cnblogs.com/hapjin/p/7599189.html本文介绍如何向线程池提交任务,并获得任务的执行结果。然后模拟线程池中的线程在执行任务的过程中抛出异常时,该如何处理。一、执行具体任务的线程类要想获得线程的执行结果,需实现Callable接......
  • js毫秒转时分秒
    constformatSeconds=(value)=>{ if(value===0||value<1000)return'0秒'; vartimestamp=parseInt(value)/1000;//毫秒转秒 //小时取余数 constremainder=timestamp%3600 //时、分、秒 lethour,minute,second; if(remainder===0){/......
  • js数组sort方法排序
    数组的sort方法可以对数组进行排序,默认是按照字符编码的顺序进行排序,可以自定义规则。sort方法会修改原数组。自定义规则简述:比较函数两个参数a和b,(a是b的后一个元素),返回a-b升序,返回b-a降序。letarr=[3,5,2,9,1];arr.sort();//默认升序arr.sort((a,b)=>{//......
  • 关于The JSON value could not be converted to System.DateTime的解决方案
    如下json格式提交到后台后报:TheJSONvaluecouldnotbeconvertedtoSystem.DateTime.Path:$.beginTime|LineNumber:3|BytePositionInLine:33.{"beginTime":"2023-06-08T08:00:00"}造成这个错误的原因为程序无法正常解析该json,主要是为了提升执行效率;Sys......
  • JSON与JAVA数据的转换
    JSON与JAVA数据的转换关键字:jsonjavaJSON-lib这个Java类包用于把bean,map和XML转换成JSON并能够把JSON转回成bean和DynaBean。下载地址:http://json-lib.sourceforge.net/还要需要的第3方包:jakartacommons-lang2.3jakartacommons-beanutils1.7.0j......
  • JS stacktrace Vue 项目过大内存泄漏
    1.运行以下命令npminstall-gincrease-memory-limitincrease-memory-limit4096mb#改成适合本机的内存2.可能会提示  "node--max-old-space-size=10240"'不是内部或外部命令,也不是可运行的程序在node_modules文件夹下的.bin文件夹搜索"%_prog%"替换成%_prog%......
  • CreateJS 动画 EaselJS 动画
    本节将介绍创建图形动画,精灵表位图动画,DOM元素动画.例子1图形动画<!DOCTYPEhtml><html><head> <metacharset="gbk"> <scripttype="text/javascript"src="easeljs-0.6.0.min.js"></script></head><body> &l......
  • 【C#】JSON转DataTable存入数据库
    由于JSON直接转DataTable可能会存在类型丢失如下:采用读取数据库表字段类型构建DataTable///<summary>///JSON转DataTale存入数据库///</summary>///<paramname="json"></param>publicstaticvoidJsonDataTableTest(stringjson){stringsql=strin......
  • .net core 因路径原因导致的JSON解析错误
    因解析json配置文件导致的错误:JsonReaderException:'0xEF'isaninvalidescapablecharacterwithinaJSONstring.Thestringshouldbecorrectlyescaped.LineNumber如何解决?{  "path":"D:\工作资料\技术资料"}改为{   "path":"D:......