Javascript实现异步编程的过程


Posted in Javascript onJune 18, 2018

相信不少人对Javascript单线程表示怀疑:为何单线程可以实现异步操作呢?其实Javascript确实是单线程的(我们不妨把这个线程称作主线程),但它实现异步操作的方式确实借助了浏览器的其他线程的帮助。那其他线程是怎么帮助Javascript主线程来实现异步的呢?答案就是任务队列(task queue)和事件循环(event loop)。

任务队列

首先,作为单线程语言,在Javascript中定义的任务都会在主线程中执行。但是并不是每个任务都会立刻执行,而这种不立刻执行的任务我们称作异步任务。相反,那些立刻执行的任务我们把它们称作同步任务。而这些异步任务都会交给浏览器的其他线程去执行,但是主线程需要了解这些异步任务执行的状态,才方便进行下一步操作。

打个比方,主线程准备做饭,所以下达一个异步任务去买菜,异步任务买完菜之后得告诉主线程:“我买完菜啦”,这个时候主线程才好开始做饭。

而我们知道因为Javascript是单线程,所以上述的“下一步操作”没法直接定义在主函数里(不然就被当做同步任务直接执行了),那这些应该定义在哪里呢?答案就是异步任务的回调函数中。在Javascript异步机制中,任务队列就是用来维护异步任务回调函数的队列。这样一个队列用来存放这些回调函数,它们会等到主线程执行完所有的同步函数之后按照先进先出的方式挨个执行。那么执行完任务队列之后呢?Javascript主线程就执行完毕了吗?当然不是,不然网页加载完毕之后,谁来处理后续与用户的交互事件(比如点击事件)呢?

事件循环

Javascript实现异步编程的过程

我们通过上图来更加形象的了解Javascript的异步机制。

执行同步任务 -> 检查任务队列中是否有任务 -> [有如果则执行] -> 检查任务队列中是否有任务 -> [有如果则执行] -> ......
可见主线程在执行完同步任务之后,会无限循环地去检查任务队列中是否有新的“任务”,如果有则执行。而这些任务包括我们在异步任务中定义的回调函数,也包括用户交互事件的回调函数。通过事件循环,Javascript不仅很好的处理了异步任务,也很好的完成了与用户交互事件的处理。因为在完成异步任务的回调函数之后,任务队列中的任务都是由事件所产生的,因此我们也把上述的循环过程叫做事件循环。

异步机制实践

console.log('定时器去买菜吧')
setTimeout(function(){
 console.log('菜买完了,主线程去做菜吧')
}, 0)
console.log('你先去买菜,我先看个世界杯')

在浏览器中执行上述代码,兴许能更好地理解Javascript的异步机制。

总结

总而言之,Javascript单线程的背后有浏览器的其他线程为其完成异步服务,这些异步任务为了和主线程通信,通过将回调函数推入到任务队列等待执行。主线程所做的就是执行完同步任务后,通过事件循环,不断地检查并执行任务队列中回调函数。

Javascript 相关文章推荐
js getBoundingClientRect() 来获取页面元素的位置
Nov 25 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
Mar 20 Javascript
node.js中的http.request.end方法使用说明
Dec 10 Javascript
详解Angularjs中的依赖注入
Mar 11 Javascript
浅析Javascript中bind()方法的使用与实现
Apr 29 Javascript
老生常谈Javascript中的原型和this指针
Oct 09 Javascript
jQuery自定义组件(导入组件)
Nov 08 Javascript
Node.js测试中的Mock文件系统详解
Nov 21 Javascript
layui-laydate时间日历控件使用方法详解
Nov 15 Javascript
如何使用 vue + d3 画一棵树
Dec 03 Javascript
使用jQuery如何写一个含验证码的登录界面
May 13 jQuery
html+vue.js 实现漂亮分页功能可兼容IE
Nov 07 Javascript
详解JS函数stack size计算方法
Jun 18 #Javascript
jQuery使用动画队列自定义动画操作示例
Jun 16 #jQuery
node.js自动上传ftp的脚本分享
Jun 16 #Javascript
Vue中props的使用详解
Jun 15 #Javascript
基于jQuery实现的设置文本区域的光标位置
Jun 15 #jQuery
深入浅析Vue全局组件与局部组件的区别
Jun 15 #Javascript
react-native android状态栏的实现
Jun 15 #Javascript
You might like
Session保存到数据库的php类分享
2011/10/24 PHP
PHP开发制作一个简单的活动日程表Calendar
2016/06/20 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
取键盘键位ASCII码的网页
2007/07/30 Javascript
IE FF OPERA都可用的弹出层实现代码
2009/09/29 Javascript
js调用css属性写法
2013/09/21 Javascript
js跑步算法的实现代码
2013/12/04 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
js弹出确认是否删除对话框
2014/03/27 Javascript
javascript实现带节日和农历的日历特效
2015/02/01 Javascript
js代码验证手机号码和电话号码是否合法
2015/07/30 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
JS实用的带停顿的逐行文本循环滚动效果实例
2016/11/23 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
jQuery实现表格冻结顶栏效果
2017/08/20 jQuery
Vue利用canvas实现移动端手写板的方法
2018/05/03 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
微信公众平台获取access_token的方法步骤
2019/03/29 Javascript
浅析Vue中拆分视图层代码的5点建议
2019/08/15 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
2020/07/12 Javascript
[03:46]显微镜下的DOTA2第七期——满血与残血
2014/06/20 DOTA
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
Pandas:DataFrame对象的基础操作方法
2018/06/07 Python
Python实用技巧之利用元组代替字典并为元组元素命名
2018/07/11 Python
python判断所输入的任意一个正整数是否为素数的两种方法
2019/06/27 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
python实现各种插值法(数值分析)
2019/07/30 Python
Python使用Matlab命令过程解析
2020/06/04 Python
python使用smtplib模块发送邮件
2020/12/17 Python
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
资深地理教师自我评价
2013/09/21 职场文书
财务分析个人的自荐书范文
2013/11/24 职场文书
十大好看的穿越动漫排名:《瑞克和莫蒂》第一,国漫《有药》在榜
2022/03/18 日漫
Golang数据类型和相互转换
2022/04/12 Golang
详解Anyscript开发指南绕过typescript类型检查
2022/09/23 Javascript