JavaScript单线程和任务队列原理解析


Posted in Javascript onFebruary 04, 2020

这篇文章主要介绍了JavaScript单线程和任务队列原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、JavaScript为什么设计为单线程?

JavaScript语言的一大特点就是单线程,换言之就是同一个时间只能做一件事。

for(var j = 0; j < 5; j++) {
 console.log(j);
}
console.log('end');

上面的代码,只有for循环执行完毕,才会执行end;

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途就是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

二、任务队列

"任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件;

我们来解释一下:

Javascript是单线程的,单线程就意味着所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。

如果排队是因为计算量太大,CPU占用高倒也情有可原,但是很多时候CPU是处于空闲状态或者有很大的空间未被使用,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),只能等结果出来,才可以往下执行。

JavaScript语言的设计者意识到,主线程完全可以不管IO设备,把这些等待中的任务挂起,先运行排在后面的任务。等到IO设备返回了结果,再去执行挂起的任务。

因此,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

具体来说,异步执行的运行机制如下。(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)

所有同步任务都在主线程上执行,形成一个执行栈

主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

主线程不断重复执行上面的第三步。

for(var j = 0; j < 5; j++) {
  console.log(j);
  setTimeout(function() {
    console.log('timeout');
  }, 0);
}

console.log('end');

//结果0 1 2 3 4 end timeout timeout timeout timeout timeout

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS简单模拟触发按钮点击功能的方法
Nov 30 Javascript
Javascript设计模式之观察者模式(推荐)
Mar 29 Javascript
浅谈js的异步执行
Oct 18 Javascript
解析Javascript单例模式概念与实例
Dec 05 Javascript
原生js实现可爱糖果数字时间特效
Dec 30 Javascript
bootstrap datetimepicker日期插件使用方法
Jan 13 Javascript
详解微信小程序 template添加绑定事件
Jun 23 Javascript
ES6模块化的import和export用法方法总结
Aug 08 Javascript
javascript中UMD规范的代码推演
Aug 29 Javascript
详解用Webpack与Babel配置ES6开发环境
Mar 12 Javascript
node使用request请求的方法
Dec 20 Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
Apr 08 Javascript
Vue中this.$nextTick的作用及用法
Feb 04 #Javascript
JS中this的4种绑定规则详解
Feb 04 #Javascript
详解JavaScript中精度失准问题及解决方法
Feb 04 #Javascript
Preload基础使用方法详解
Feb 03 #Javascript
使用PreloadJS加载图片资源的基础方法详解
Feb 03 #Javascript
使用preload预加载页面资源时注意事项
Feb 03 #Javascript
jQuery实现小火箭返回顶部特效
Feb 03 #jQuery
You might like
咖啡冲泡指南 咖啡有哪些制作方式 单品咖啡 意式咖啡
2021/03/06 冲泡冲煮
php获取远程文件的内容和大小
2015/11/03 PHP
PHP设计模式之模板方法模式定义与用法详解
2018/04/02 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
PHP配置ZendOpcache插件加速
2019/02/14 PHP
php+lottery.js实现九宫格抽奖功能
2019/07/21 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
使用jquery.validate自定义方法实现&quot;手机号码或者固话至少填写一个&quot;的逻辑验证
2014/09/01 Javascript
sogou地图API用法实例教程
2014/09/11 Javascript
详谈js遍历集合(Array,Map,Set)
2017/04/06 Javascript
vue使用drag与drop实现拖拽的示例代码
2017/09/07 Javascript
webpack热模块替换(HMR)/热更新的方法
2018/04/05 Javascript
在 vue-cli v3.0 中使用 SCSS/SASS的方法
2018/06/14 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
2018/09/17 Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
JsonServer安装及启动过程图解
2020/02/28 Javascript
如何手写一个简易的 Vuex
2020/10/10 Javascript
[01:01:41]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第二场 1月31日
2021/03/11 DOTA
Python创建文件和追加文件内容实例
2014/10/21 Python
Python常用知识点汇总
2016/05/08 Python
python实现字符串连接的三种方法及其效率、适用场景详解
2017/01/13 Python
Linux CentOS Python开发环境搭建教程
2018/11/28 Python
python导入pandas具体步骤方法
2019/06/23 Python
python实现连连看辅助之图像识别延伸
2019/07/17 Python
如何利用Python写个坦克大战
2020/11/18 Python
python温度转换华氏温度实现代码
2020/12/06 Python
MVMT手表官方网站:时尚又实惠的高品质手表
2016/12/04 全球购物
粉红色的鲸鱼:Vineyard Vines
2018/02/17 全球购物
先进班级集体事迹材料
2014/01/30 职场文书
党员公开承诺书范文
2014/03/25 职场文书
关于安全的演讲稿
2014/05/09 职场文书
教师党员公开承诺事项
2014/05/28 职场文书
公民代理授权委托书
2014/09/24 职场文书
群众路线个人整改方案
2014/10/25 职场文书
公司员工违纪检讨书
2015/05/05 职场文书