继续 JS引擎线程的执行过程的三个阶段(一) 内容, 如下:

三. 执行阶段

1. 网页的线程

永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS引擎线程执行, 不参与代码解析与执行。

  • JS引擎线程: 也称为JS内核,负责解析执行Javascript脚本程序的主线程(例如V8引擎)

  • 事件触发线程: 归属于浏览器内核进程,不受JS引擎线程控制。主要用于控制事件(例如鼠标,键盘等事件),当该事件被触发时候,事件触发线程就会把该事件的处理函数推进事件队列,等待JS引擎线程执行

  • 定时器触发线程:主要控制计时器setInterval和延时器setTimeout,用于定时器的计时,计时完毕,满足定时器的触发条件,则将定时器的处理函数推进事件队列中,等待JS引擎线程执行。 注:W3C在HTML标准中规定setTimeout低于4ms的时间间隔算为4ms。

  • HTTP异步请求线程:通过XMLHttpRequest连接后,通过浏览器新开的一个线程,监控readyState状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推进事件队列中,等待JS引擎线程执行。 注:浏览器对通一域名请求的并发连接数是有限制的,Chrome和Firefox限制数为6个,ie8则为10个。

2. 宏任务

宏任务(macro-task)可分为同步任务和异步任务:

  • 同步任务指的是在JS引擎主线程上按顺序执行的任务,只有前一个任务执行完毕后,才能执行后一个任务,形成一个执行栈(函数调用栈)。

  • 异步任务指的是不直接进入JS引擎主线程,而是满足触发条件时,相关的线程将该异步任务推进任务队列(task queue),等待JS引擎主线程上的任务执行完毕,空闲时读取执行的任务,例如异步Ajax,DOM事件,setTimeout等。

理解宏任务中同步任务和异步任务的执行顺序,那么就相当于理解了JS异步执行机制–事件循环(Event Loop)。

3. 事件循环

事件循环可以理解成由三部分组成,分别是:

  • 主线程执行栈

  • 异步任务等待触发

  • 任务队列

任务队列(task queue)就是以队列的数据结构对事件任务进行管理,特点是先进先出,后进后出。

setTimeout和setInterval的区别:

  • setTimeout是在到了指定时间的时候就把事件推到任务队列中,只有当在任务队列中的setTimeout事件被主线程执行后,才会继续再次在到了指定时间的时候把事件推到任务队列,那么setTimeout的事件执行肯定比指定的时间要久,具体相差多少跟代码执行时间有关

  • setInterval则是每次都精确的隔一段时间就向任务队列推入一个事件,无论上一个setInterval事件是否已经执行,所以有可能存在setInterval的事件任务累积,导致setInterval的代码重复连续执行多次,影响页面性能。

4. 微任务

微任务是在es6和node环境中出现的一个任务类型,如果不考虑es6和node环境的话,我们只需要理解宏任务事件循环的执行过程就已经足够了,但是到了es6和node环境,我们就需要理解微任务的执行顺序了。 微任务(micro-task)的API主要有:Promise, process.nextTick

例子理解:

console.log('script start');setTimeout(function() {console.log('setTimeout');
}, 0);Promise.resolve().then(function() {console.log('promise1');
}).then(function() {console.log('promise2');
});console.log('script end');

  

 

执行过程如下:

  • 代码块通过语法分析和预编译后,进入执行阶段,当JS引擎主线程执行到console.log('script start');,JS引擎主线程认为该任务是同步任务,所以立刻执行输出script start,然后继续向下执行;

  • JS引擎主线程执行到setTimeout(function() { console.log('setTimeout'); }, 0);,JS引擎主线程认为setTimeout是异步任务API,则向浏览器内核进程申请开启定时器线程进行计时和控制该setTimeout任务。由于W3C在HTML标准中规定setTimeout低于4ms的时间间隔算为4ms,那么当计时到4ms时,定时器线程就把该回调处理函数推进任务队列中等待主线程执行,然后JS引擎主线程继续向下执行

  • JS引擎主线程执行到Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); });,JS引擎主线程认为Promise是一个微任务,这把该任务划分为微任务,等待执行

  • JS引擎主线程执行到console.log('script end');,JS引擎主线程认为该任务是同步任务,所以立刻执行输出script end

  • 主线程上的宏任务执行完毕,则开始检测是否存在可执行的微任务,检测到一个Promise微任务,那么立刻执行,输出promise1和promise2

  • 微任务执行完毕,主线程开始读取任务队列中的事件任务setTimeout,推入主线程形成新宏任务,然后在主线程中执行,输出setTimeout

最后的输出结果即为:

script start
script end
promise1
promise2
setTimeout

  

 

文章参考:

https://github.com/yygmind/blog/issues/12

https://heyingye.github.io/2018/03/19/js引擎的执行过程(一)

https://heyingye.github.io/2018/03/26/js引擎的执行过程(二)

https://github.com/yygmind/blog

转载于:https://www.cnblogs.com/BoatGina/p/10433551.html

JS引擎线程的执行过程的三个阶段(二)相关推荐

  1. JS引擎线程的执行过程的三个阶段

    浏览器首先按顺序加载由<script>标签分割的js代码块,加载js代码块完毕后,立刻进入以下三个阶段,然后再按顺序查找下一个代码块,再继续执行以下三个阶段,无论是外部脚本文件(不异步加载 ...

  2. java map集合 事务控制_对象回收过程?线程池执行过程? map原理?集合类关系?synchronized 和 volatile ? 同一个类的方法事务传播控制还有作用吗?java 锁...

    1.  对象回收过程? 可达性分析算法: 如果一个对象从 GC Roots 不可达时,则证明此对象不可用. 通过一系列称为GC ROOTS的对象作为起点,从这些起点往下搜索,搜索走过的路径 称为引用链 ...

  3. mysql sql执行过程_MySQL探秘(二):SQL语句执行过程详解

    昔日庖丁解牛,未见全牛,所赖者是其对牛内部骨架结构的了解,对于MySQL亦是如此,只有更加全面地了解SQL语句执行的每个过程,才能更好的进行SQL的设计和优化. 当希望MySQL能够以更高的性能运行查 ...

  4. 深入解析Node.js setTimeout方法的执行过程

    深入了解setTimeout源码之前,本有两个选择.一是通过chromium源码分析,二是通过Node.js源码分析.后来发现第一种方案的源码获取成本太大,于是从Node官网获取了几十兆的代码用来了解 ...

  5. 实战并发编程 - 06线程在执行过程中的状态是如何流转的

    文章目录 线程的生命周期 线程的状态流转图 线程各个状态说明 NEW(初始化状态) RUNNABLE(就绪,运行中状态) RUNNING 运行中状态 BLOCKED(阻塞状态) WAITING(等待状 ...

  6. js 异步执行_js执行过程你了解多少?

    来公众号:「九零后重庆崽儿」找我,一起学前端. 本文首发在: js执行过程你了解多少? - 重庆崽儿brand的个人主页​www.brandhuang.com 文章自己整理自网络,如有问题欢迎在知乎或 ...

  7. MySQL再叙(体系结构、存储引擎、索引、SQL执行过程)

    文章目录 体系结构 存储引擎 SQL执行过程 select的执行过程 update的执行过程 索引 小结 提起MySQL,大家一定不陌生,MySQL是最流行的关系型数据库管理系统,MySQL的历史可以 ...

  8. 深入理解浏览器解析和执行过程

    在我们公司的业务场景中,有很大一部分用户是使用老款安卓机浏览页面,这些老款安卓机性能较差,如果优化不足,页面的卡顿现象会更加明显,此时页面性能优化的重要性就凸显出现.优化页面的性能,需要对浏览器的渲染 ...

  9. 前端读者 | 由setTimeout引发的JS引擎运行机制的研究

    本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发 ...

最新文章

  1. 利用gcc的__attribute__编译属性section子项构建初始化函数表【转】
  2. Android调用相机拍摄照片并显示到 ImageView控件中
  3. source ~/.bashrc 什么意思
  4. vue学习笔记-01-前端的发展历史(从后端到前端,再到前后端分离,再到全栈)
  5. 【中级】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 01 - 文件组成详细分析
  6. python获取命令行参数_【整理】Python中如何获得并处理命令行参数
  7. 【报告分享】85后、95后宝妈人群洞察报告.pdf(附下载链接)
  8. RabbitMQ SSL安全认证
  9. 6款主流PDF编辑器测试,快来看看哪一款最适合你吧
  10. 计算机专业英语(一)学习方法
  11. 三维错切变换矩阵_三维基本几何变换矩阵.PPT
  12. spring(春天)
  13. (转)ANDROID强制锁定竖屏_APP固定设置竖屏或横屏
  14. STM32——GPIO的CRL、CRH和CNF与MODE的关系
  15. 【LaTeX教程】七.LaTeX数学公式初步
  16. linux多进程和多线程分析之一
  17. 前端开发免费学习资源分享
  18. 用VBA做一个儿童识字,数字考察游戏(持续更新中)
  19. 日本小学生入校时校长说的话
  20. Java富文本设置行间距,如何解决富文本设置行间距的单行带间距问题

热门文章

  1. 在Ubuntu 18.04上安装Nginx
  2. sql除外语句_SQL除外
  3. python集合_Python集
  4. 迅捷cad_迅捷功能
  5. Java PreparedStatement
  6. quicksort算法_QuickSort算法–用C,Java,Python实现
  7. .net 编译、反编译、查壳、脱壳、反混淆工具
  8. React Native项目使用react-apollo实现更新缓存的两种方式
  9. NIO-ByteBuffer
  10. Spring Cloud Config客户端使用