试着讲清楚:js代码运行机制

一、 js运行机制

js执行引擎

经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了。

js代码如何运行?

在js代码执行的时候,js的代码是按照顺序执行的,从上到下,这个时候是同步的,不过,有几个例外:

  • 异步的网络请求
  • 事件绑定、事件监听器
  • 时间触发函数

我们模拟一下,js引擎遇到这三类代码的情况:

  1. js执行的好好的,正在顺序执行代码,这个时候呢,遇到了异步的网络请求的代码,这个时候,直接js代码调用之后,就继续执行之后的js代码了,并没有等待网络请求的结果,js代码执行是单线程的(不考虑h5),那么肯定异步网络请求调用之后,肯定不是js执行引擎管理了,问题一:谁在等待,谁之后通知js执行引擎结果,毕竟是js代码就得js引擎是执行。
  2. 有了第一个问题,我们已经知道肯定有其它的东西参与了上面的事情了,先放着,之后呢js有欢乐的往下执行,遇到了事件绑定和事件监听函数,哦,这个js调用之后,也是继续往下走的,并没有调用那些函数之类的,我们知道,事件函数只有在事件触发的时候会起作用,js代码js执行引擎执行。那么问题二:谁把事件关联的函数保存的,以便接收事件触发选择正确的事件处理函数,通知js执行引擎?
  3. js在遇到setTimeout和setInternal函数的时候,也是不直接执行,然后处理之后的代码的,那么问题三:谁在监视时间流逝选择合适的触发函数通知js引擎执行的?

以上3点是在自己学习js的运行机制和js执行引擎的时候,遇到了3个问题,那么3个问题其中的js执行js代码,但是监视肯定不是js执行引擎,答案如下:

  1. 异步网络请求线程
  2. 事件触发线程
  3. 定时触发器线程

以上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代码执行的交互就了解了。(渲染线程是每次都需要切换的吗?这个已经属于性能优化内容了,就暂时不了解了)

原文地址:https://www.cnblogs.com/fenqi/p/8544818.html

时间: 2024-07-30 00:35:16

试着讲清楚:js代码运行机制的相关文章

JS的运行机制

代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. 案例:2个代码块 <script type="text/javascript"> console.log("这是代码块一"); </script> <script type="text/javascript">

js 代码运行中插入交互

js 代码运行中插入交互 背景 最近突发奇想,如果能在 js 运行时插入用户操作,是否就可以看到每一步的状态了呢? 以冒泡排序为例,最终实现的效果是这样的: 思路 我们知道,如果代码中 await 一个 promise,那么这行代码需要等到 promise 状态为 resolved 时才能向下继续执行. 例如: await new Promise(resolve=>{}),这样代码将会一直在这里等待下去,因为这个 Promise 的状态为pending. 有了这个思路,我们只需想办法将这个 pr

JS代码执行机制

JS代码从编译到执行 我们写出一段JS代码,JS的引擎并不是按照我们书写的顺序从上到下顺序编译并且执行的,首先是按照自己的规则对我们的代码先进行编译,然后从上到下执行编译的代码. 在全局作用域中,JS首先会对我们的函数进行声明,然后就是我们经常听到的变量提升机制,然后才是按照我们书写代码的顺序,来进行编译,然后在执行编译的代码. 看如下代码: function fn(){ console.log(a); } fn(); var a = "value"; 非常常见的一个面试题fn函数执行

浏览器执行js代码的机制--对于我们深入了解js有很大的帮助,同时面试时候也都能用得到。

前端小菜又来了,这些天每天工作,晚上学习太累了.趁星期天给自己放个假.写完这个博客就要出去high了.鸡冻.接下来进入正题啦, 你可能要问,我们学习这个有什么用啊?这样我先给大家来个小小的面试题. alert(a);C1: var a = 1;F2: function a() { alert(2); } alert(a);c2: var a = 3; alert(a);F2: function a() { alert(3) } alert(a);如果你知道答案,那么恭喜你,接下来别听我bb了.如

Java代码运行机制

Java代码编译后生成一种与平台无关的字节码(也就是class文件).当然,这种字节码不是可执行的,必须使用Java解释器来解释执行.负责解释执行字节码文件的是Java虚拟机,即JVM.JVM是可运行Java字节码文件的虚拟计算机.所有平台上的JVM向编译器提供相同的编程接口,而编译器只需要面向虚拟机,生成虚拟机理解的代码,然后由虚拟机来解释执行.在一些虚拟机的实现中,还会将虚拟机代码转换成特定系统的机器码执行,从而提高执行效率. 当我们调用Java命令运行某个java程序时,该命令将会启动一条

剖析 Vue.js 内部运行机制 (1)

1. new Vue() 之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周 期.事件. props. methods. data. computed 与 watch 等.其中最重要的是通过 Object.defineProperty 设置 setter 与 getter 函数,用来实现「 响应式」以及「 依赖收集」 2. mounted 初始化之后调用 $mount 会挂载组件,如果是运行时编译,即不存在 render function 但是存在

js运行机制

先来看一道题目然后再来详细的说明js的运行机制,下面的一段代码执行顺序是什么 console.log(1); setTimeout(function () { console.log(2); }, 0); console.log(3); console.log(4); 测试得到的结果是1,3,4,2,至于为什么会这么执行,我们来看下面的内容

从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理(转)

前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----超长文+多图预警,需要花费不少时间.---- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏览器多进程.浏览器内核多线程.JS单线程.JS运行机制的区别.那么请回复我,一定是我写的还不够清晰,我来改... ----正文开始---- 最近发现有不少介绍JS单线程运行机制的文章,但是发现很多都仅仅是介绍某一部分的知识,而且各个地方的说法还不统一,容易造成困惑. 因此准备梳理这块知识点,结合已有的认知,基于网上的大量参

【朴灵评注】JavaScript 运行机制详解:再谈Event Loop

PS: 我先旁观下大师们的讨论,得多看书了~ 别人说的:“看了一下不觉得评注对到哪里去,只有吹毛求疵之感. 比如同步异步介绍,本来就无大错:比如node图里面的OS operation,推敲一下就可以猜到那是指同步操作(自然不走event loop了):至于watcher啥的,显然只是实现上的特色,即使用同一个queue实现也未尝不可” [原帖: http://www.ruanyifeng.com/blog/2014/10/event-loop.html 作者:阮一峰] 一年前,我写了一篇<什么