试着讲清楚:js代码运行机制
一、 js运行机制
js执行引擎
经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了。
js代码如何运行?
在js代码执行的时候,js的代码是按照顺序执行的,从上到下,这个时候是同步的,不过,有几个例外:
- 异步的网络请求
- 事件绑定、事件监听器
- 时间触发函数
我们模拟一下,js引擎遇到这三类代码的情况:
js执行的好好的,正在顺序执行代码,这个时候呢,遇到了异步的网络请求的代码,这个时候,直接js代码调用之后,就继续执行之后的js代码了,并没有等待网络请求的结果,js代码执行是单线程的(不考虑h5),那么肯定异步网络请求调用之后,肯定不是js执行引擎管理了,问题一:谁在等待,谁之后通知js执行引擎结果,毕竟是js代码就得js引擎是执行。
有了第一个问题,我们已经知道肯定有其它的东西参与了上面的事情了,先放着,之后呢js有欢乐的往下执行,遇到了事件绑定和事件监听函数,哦,这个js调用之后,也是继续往下走的,并没有调用那些函数之类的,我们知道,事件函数只有在事件触发的时候会起作用,js代码js执行引擎执行。那么问题二:谁把事件关联的函数保存的,以便接收事件触发选择正确的事件处理函数,通知js执行引擎?
js在遇到setTimeout和setInternal函数的时候,也是不直接执行,然后处理之后的代码的,那么问题三:谁在监视时间流逝选择合适的触发函数通知js引擎执行的?
以上3点是在自己学习js的运行机制和js执行引擎的时候,遇到了3个问题,那么3个问题其中的js执行js代码,但是监视肯定不是js执行引擎,答案如下:
- 异步网络请求线程
- 事件触发线程
- 定时触发器线程
以上3个线程是独立于js引擎之外,帮助处理这3类代码的,所以啊,千万不要认为js引擎什么都做,加上gui渲染线程,js执行引擎线程,5个线程齐了。
以上我们了解了js执行的代码和3个额外的线程协助下,js执行代码构建了完备的环境了,但是js执行引擎是如何执行这3类线程给的函数的,答案是队列(暂且叫做Message Queue),3个线程选择好了需要执行的函数之后,会进行包装成一个结构(消息),放到队列里面,js执行玩代码之后,会循环的在这个队列里面取消息,取到了,那么就执行,取不到了就等待。
以上的一个执行结构,那么我们就可以得出一个结论,js在遇到3类代码的时候,一定滞后于同步代码的,因为同步代码执行完成之后,js才会从队列中取一条消息,来执行,并且执行完成之后才会再取一条。
以上也就是为什么时间处理函数总是在同步代码之后执行的原因,异步网络请求的回调函数也在同步代码执行完成之后调用的原理,就是因为这3类函数被3类线程放到了队列里了,而队列里面的代码在js执行完同步代码之后才能执行。
setTimeout为什么不能恰到好处的执行呢,这是因为定时触发器线程只是在时间到了之后,把应该执行的函数进行封装放到队列里面而已,具体什么时候执行还得看之前队列含有多少消息没有被处理。
二、gui渲染线程与js执行引擎的交互机制
上面说了3个执行线程与js执行引擎的交互,这个基本上没有问题了,这下说说渲染与js代码之间的交互。
在写js代码初期,肯定遇到过js代码执行性能问题,然后页面直接就不动弹了,这个时候其实可以得出来一个结论,js执行的时候,渲染线程是阻塞的,之后查了资料,发现这个定义更准确的说法是:js执行引擎的线程和gui渲染线程是互斥的。
这也能解释为什么js执行时间长后渲染不动的问题了。那么一个新的问题来了,如果是这样的话,那么渲染引擎肯定就不能渲染,至少在js队列不空的情况下,根本没有机会渲染的,那么就可以做一个代码不断的使用setInternal不断的往队列里面填消息。事实真的是这样吗?
肯定不是这样的,实际的浏览器没有是这样的,那么到底是哪块让js引擎和gui执行引擎的线程进行切换的,同步代码肯定不行,那么就是队列这块了,肯定不是队列为空的情况切换的,因为实际的js代码在改了之后基本上就渲染了,那么基本上确定,是在每一次消息之间执行的,因为js代码在执行的时候是同步的,做了这个假设之后,再查了大量的资料,有一篇文章是这样描述的,在每次执行完一个消息之后,马上切换到渲染线程执行渲染效果,然后渲染完成再切换js代码执行取下一个消息。
至此渲染和js代码执行的交互就了解了。(渲染线程是每次都需要切换的吗?这个已经属于性能优化内容了,就暂时不了解了)
试着讲清楚:js代码运行机制的更多相关文章
- JS的运行机制
代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. ...
- 关于js内部运行机制的一本好书
读<单页Web应用一书>,第二章讲了js内部运行机制,感觉棒极了.之前读<你不知道的js>,看的云里雾里,似懂非懂.没想到单页Web一书将此内容讲的如此通俗易懂,好多困惑已久的 ...
- 《JavaScript总结》js的运行机制
首先大家都知道javascript是单线程语言. 什么是单线程呢?比如我们去车站买票,只有一个售票窗口,大家排队买票,需要前面的人买完票,后面的人才能买票. 那为什么javascript不能是多线程呢 ...
- JS代码执行机制
JS代码从编译到执行 我们写出一段JS代码,JS的引擎并不是按照我们书写的顺序从上到下顺序编译并且执行的,首先是按照自己的规则对我们的代码先进行编译,然后从上到下执行编译的代码. 在全局作用域中,JS ...
- 从Event Loop谈JS的运行机制
这里主要是结合Event Loop来谈JS代码是如何运行的. 事件循环对于我们平时开发可以说是特别重要,可以让我们写出更好的代码. 到这里相信我们已经知道了JS引擎是单线程,而且这里会用到前面说的的几 ...
- JS代码运行延迟
还是上篇文章的项目. 现在是屏幕上需要显示九张图表,刚好用一张3X3的表格来显示.但是负责这块内容的同事始终没法让九张图表同时显示,有些图表的位置空了出来. 大家百思不得其解,最后只得求助技术经理. ...
- js setTimeout运行机制
在开始之前先看个面试例子 为什么会是0 1 2 2,而不是 0 0 1 1 再来看个例子 输出结果是4个undefined,为何不是1,2,3,4? 这是为什么呢,这是因为setTimeout是异步的 ...
- 前端读者 | 由setTimeout引发的JS引擎运行机制的研究
本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发 ...
- 浏览器执行js代码的机制--对于我们深入了解js有很大的帮助,同时面试时候也都能用得到。
前端小菜又来了,这些天每天工作,晚上学习太累了.趁星期天给自己放个假.写完这个博客就要出去high了.鸡冻.接下来进入正题啦, 你可能要问,我们学习这个有什么用啊?这样我先给大家来个小小的面试题. a ...
随机推荐
- CometD的消息推送
CometD 框架 CometD 框架是基于 HTTP 的事件驱动通信解决方案.CometD 框架提供了一个 Java 服务器部件和一个 Java 客户端部件,还有一个基于 jQuery 和 Dojo ...
- [Python Study Notes]异常处理
正则表达式 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误.你可以使用该功能来调试python程序. 异常处理 断言(Assertions) python标准异常 ...
- WPF DataTriger 用法示例代码
用法1: <DataGridTemplateColumn Header="{lex:LocText ExamineRoom}"> <DataGridTemplat ...
- 【技术干货】git常用命令
2.1 git init语法: git init在当前目录初始化git仓库,适用于尚未使用git管理的项目2.2 git clone语法: git clone <url>例如: git c ...
- 分布式代码管理系统Git实践
1.1 版本管理工具介绍 什么是版本管理工具 为什么要使用版本管理工具? 老板要求小明写一个可行性报告,当他写完给老板看后,结果-- Git简介 早先linux内核代码托管在B ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...
- 我的docker全套流程例子
本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 下文是自己从搭建docker到docker里安装mysql到 ...
- 10分钟入门kubernetes(上)
kubernetes简称k8s, 主要用途是automate deployment, scaling, and managment of containerized applications.是目前非 ...
- [翻译]编写高性能 .NET 代码 第二章:垃圾回收
返回目录 第二章:垃圾回收 垃圾回收是你开发工作中要了解的最重要的事情.它是造成性能问题里最显著的原因,但只要你保持持续的关注(代码审查,监控数据)就可以很快修复这些问题.我这里说的"显著的 ...
- Yii2 灵活加载js、css
Yii2.0对于CSS/js 管理,使用AssetBundle资源包类. 视图如何按需加载CSS/JS ? 资源包定义: backend/assets/AppAsset.PHP <?php na ...