详解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版本A*寻路算法
Dec 22 Javascript
关于取不到由location.href提交而来的上级页面地址的解决办法
Jul 30 Javascript
javascript针对DOM的应用分析(二)
Apr 15 Javascript
浅谈JavaScript实现面向对象中的类
Dec 09 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
Jan 29 Javascript
bootstrap fileinput 上传插件的基础使用
Feb 17 Javascript
vue使用 better-scroll的参数和方法详解
Jan 25 Javascript
浅析Angular19 自定义表单控件
Jan 31 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
Mar 06 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
Apr 25 Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
Jun 04 Javascript
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
May 18 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
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
linux下编译安装memcached服务
2014/08/03 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
js FLASH幻灯片字符串中有连接符&的处理方法
2012/03/01 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
解析img图片没找到onerror事件 Stack overflow at line: 0
2013/12/23 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
如何使用angularJs
2017/05/08 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
Mac中安装nvm的教程分享
2017/12/11 Javascript
JavaScript 数组去重并统计重复元素出现的次数实例
2017/12/14 Javascript
jackson解析json字符串,首字母大写会自动转为小写的方法
2017/12/22 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
Python set集合类型操作总结
2014/11/07 Python
Python3读取文件常用方法实例分析
2015/05/22 Python
详解django中自定义标签和过滤器
2017/07/03 Python
Python使用Flask-SQLAlchemy连接数据库操作示例
2018/08/31 Python
python基础知识(一)变量与简单数据类型详解
2019/04/17 Python
Python 使用指定的网卡发送HTTP请求的实例
2019/08/21 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
django中瀑布流写法实例代码
2019/10/14 Python
深入理解Tensorflow中的masking和padding
2020/02/24 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
2020/02/26 Python
Python闭包装饰器使用方法汇总
2020/06/29 Python
解决python便携版无法直接运行py文件的问题
2020/09/01 Python
谈谈对css属性box-sizing的了解
2017/01/04 HTML / CSS
从一次项目重构说起CSS3自定义变量在项目的使用方法
2021/03/01 HTML / CSS
美国标志性加大尺码时装品牌:Ashley Stewart
2016/12/15 全球购物
餐饮加盟计划书
2014/01/10 职场文书
逃课打麻将检讨书
2014/10/05 职场文书
党员评议表自我评价范文
2014/10/20 职场文书
2015教师见习期工作总结
2014/12/12 职场文书
2015入党自传书范文
2015/06/26 职场文书