详解JavaScript执行模型


Posted in Javascript onNovember 16, 2020

JavaScript执行模型

引言

JavaScript是一个单线程(Single-threaded)异步(Asynchronous)非阻塞(Non-blocking)并发(Concurrent)语言,这些语言效果通过一个调用栈(Call Stack)、一个事件循环(Event Loop)、一个回调队列(Callback Queue)有些时候也叫任务队列(Task Queue)与跟运行环境相关的API组成。

概念

调用栈 Call Stack

调用栈是一个LIFO后进先出数据结构的函数运行栈,它内部的数据结构为函数帧。当在JavaScript中调用一个函数时,它将被压入栈中,当这个函数内部还有另一个函数被调用时,另一个函数将会被压入栈顶,直到其内部没有更多调用,栈顶函数将会被以单线程方式执行并出栈,直到最后一个函数帧出栈。JavaScript语言特性中的单线程就是指的调用栈的单线程运行。

function multiply(a, b) {
 return a * b;
}

function square(n) {
 return multiply(n, n)
}

function printSquare(n) {
 console.log(square(n));
}

printSquare(4);

首先调用栈压入main(),扫描到printSquare()函数调用调用栈压入printSquare(4)printSquare函数内部调用square(n)该函数被压入栈,同理multiply(n, n)函数也被压入栈且没有更多调用,JavaScript引擎开始执行栈顶函数multiply(n, n)返回结果并出栈,以此类推直到main()函数出栈。

调用栈有一个意外情况,当函数递归调用其自身时调用栈将溢出,执行环境将报错。

function foo() {
 foo();
}
foo();

任务队列 Task Queue

任务队列是WebAPI的一部分,也就是说它本身并不是ECMAScript标准的一部分,而是运行环境自行实现的。任务队列是所有回调函数排队执行的FIFO先进先出队列,它的单位是任务(Task),每个任务都关联着一个用于处理这个任务的回调函数。在事件循环(Event Loop)中会将任务队列内的函数压入调用栈执行并出队列,直至为空。

任务队列在浏览器的实现中被分为了宏任务队列(macrotask queue)和微任务队列(microtask queue),它们分别个自承载宏任务(macrotask)和微任务(microtask)的排队,其中宏任务队列与宏任务又被默认为常规的任务队列与任务。

当调用栈内所有调用都完成执行后,事件轮询会在每次处理宏任务队列的一个宏任务后处理微任务队列的全部微任务,也就是微任务基本会在宏任务处理之前被处理。微任务处理中间不会被UI或网络事件处理被执行,微任务执行是连续的。

会被添加到宏任务的方法的回调有:

  • script:script标签中的代码解析运行
  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI rendering:UI渲染,每16.6ms放到队列上一次,60fps,如果调用栈被占用则会被阻塞

会被添加到微任务的Web API方法有:

会被添加到微任务的Web API方法有:

  • process.nextTick:Node提供的
  • Promise
  • Object.observe
  • MutationObserver

微任务只会从我们编写的代码中产生,宏任务既可能从我们编写的代码中产生也可能从浏览器本身事件、渲染、IO产生。

事件循环 Event Loop

事件循环是JavaScript的事件处理机制,它会一直轮询消息队列,当满足调用栈为空且消息队列不为空时,它将把消息队列队头的消息压入执行栈。这样的机制保证了函数不会被中断,不会有线程切换带来的数据不一致等情况

事件循环在调用栈为空时轮询,顺序为

1.找到任务队列(宏任务队列)的最早被添加的任务并将其添加到调用栈执行

2.执行所有微任务队列内的任务

  • 当微任务队列不为空时找到微任务队列最早被添加的任务并将其添加到调用栈执行

3.渲染所有变化
4.如果宏任务队列为空等待宏任务出现
5.返回步骤1

JavaScript运行时 Runtime

详解JavaScript执行模型

浏览器的JavaScript代码执行也就是调用栈与堆(用于储存变量对象等)由JavaScript引擎提供,用的比较多的是谷歌的V8引擎,Chrome、Edge浏览器、Nodejs均使用该引擎。

事件循环Event Loop、任务队列Task Queue(回调队列Callback Queue)、WebAPI或Node API由运行环境提供。

以上就是详解JavaScript执行模型的详细内容,更多关于JavaScript执行模型的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JS 动态获取节点代码innerHTML分析 [IE,FF]
Nov 30 Javascript
jQuery 位置函数offset,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft
Mar 23 Javascript
推荐30个新鲜出炉的精美 jQuery 效果
Mar 26 Javascript
JS实现图片预加载无需等待
Dec 21 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
Jan 04 Javascript
JavaScript中prototype为对象添加属性的误区介绍
Oct 15 Javascript
JavaScript中使用Math.PI圆周率属性的方法
Jun 14 Javascript
JavaScript中的pow()方法使用详解
Jun 15 Javascript
基于jquery实现左右按钮点击的图片切换效果
Jan 27 Javascript
js实现上一页下一页的效果【附代码】
Mar 10 Javascript
jQuery中show与hide方法用法示例
Sep 16 Javascript
详解vue 数据传递的方法
Apr 19 Javascript
Vue 实现拨打电话操作
Nov 16 #Javascript
微信小程序实现页面左右滑动
Nov 16 #Javascript
Vertx基于EventBus发送接受自定义对象
Nov 16 #Javascript
vue+echarts+datav大屏数据展示及实现中国地图省市县下钻功能
Nov 16 #Javascript
angular8.5集成TinyMce5的使用和详细配置(推荐)
Nov 16 #Javascript
js实现纯前端压缩图片
Nov 16 #Javascript
Vue基于localStorage存储信息代码实例
Nov 16 #Javascript
You might like
世界收音机发展史
2021/03/01 无线电
利用discuz实现PHP大文件上传应用实例代码
2008/11/14 PHP
一贴学会PHP 新手入门教程
2009/08/03 PHP
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
Laravel实现用户注册和登录
2015/01/23 PHP
php实现的后台表格分页功能示例
2017/10/23 PHP
PHP hebrev()函数用法讲解
2019/02/21 PHP
firefox插件Firebug的使用教程
2010/01/02 Javascript
jQuery 方法大全方便学习参考
2010/02/25 Javascript
jQuery UI 应用不同Theme的办法
2010/09/12 Javascript
contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2011/09/13 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
2016/04/01 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
vue2项目使用sass的示例代码
2017/06/28 Javascript
JavaScript之iterable_动力节点Java学院整理
2017/06/29 Javascript
VUE element-ui 写个复用Table组件的示例代码
2017/11/18 Javascript
js将键值对字符串转为json字符串的方法
2018/03/30 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
[01:01:18]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#2COL VS LGD
2016/03/03 DOTA
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
Python实现的递归神经网络简单示例
2017/08/11 Python
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
浅谈Python中文件夹和python package包的区别
2020/06/01 Python
python3检查字典传入函数键是否齐全的实例
2020/06/05 Python
python读取hdfs并返回dataframe教程
2020/06/05 Python
HTML5 新标签全部总汇(推荐)
2016/06/13 HTML / CSS
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
宝拉珍选英国官网:Paula’s Choice英国
2019/05/29 全球购物
MIS软件工程师的面试题
2016/04/22 面试题
入党积极分子介绍信
2014/01/17 职场文书
2014四风问题对照检查材料范文
2014/09/15 职场文书
县委务虚会发言材料
2014/10/20 职场文书
2015年小学美术工作总结
2015/05/25 职场文书
解析:创业计划书和商业计划书二者之间到底有什么区别
2019/08/14 职场文书