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重写alert控件(适合学习js的新手朋友)
Aug 24 Javascript
js常用系统函数用法实例分析
Jan 12 Javascript
javascript实现了照片拖拽点击置顶的照片墙代码
Apr 03 Javascript
自定义require函数让浏览器按需加载Js文件
Nov 24 Javascript
JS触摸与手势事件详解
May 09 Javascript
yarn的使用与升级Node.js的方法详解
Jun 04 Javascript
Angularjs上传图片实例详解
Aug 06 Javascript
基于ionic实现下拉刷新功能
May 10 Javascript
jQuery md5加密插件jQuery.md5.js用法示例
Aug 24 jQuery
详解vuex commit保存数据技巧
Dec 25 Javascript
使用Node.js实现base64和png文件相互转换的方法
Mar 11 Javascript
js实现扫雷源代码
Nov 27 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
如何对PHP程序中的常见漏洞进行攻击(上)
2006/10/09 PHP
ThinkPHP php 框架学习笔记
2009/10/30 PHP
基于PHP异步执行的常用方式详解
2013/06/03 PHP
分享PHP源码批量抓取远程网页图片并保存到本地的实现方法
2015/12/01 PHP
解决Yii2邮件发送结果返回成功,但接收不到邮件的问题
2017/05/23 PHP
javascript入门·动态的时钟,显示完整的一些方法,新年倒计时
2007/10/01 Javascript
JQuery魔力之$("tagName")与selector
2012/03/05 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
jQuery 中$(this).index与$.each的使用指南
2014/11/20 Javascript
node+express+jade制作简单网站指南
2014/11/26 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
IE6兼容透明背景图片及解决方案
2015/08/19 Javascript
深入解析JavaScript编程中的this关键字使用
2015/11/09 Javascript
谈谈对offsetleft兼容性的理解
2015/11/11 Javascript
jquery dataTable 后台加载数据并分页实例代码
2017/06/07 jQuery
微信小程序中使用Promise进行异步流程处理的实例详解
2017/08/17 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
jQuery实现验证表单密码一致性及正则表达式验证邮箱、手机号的方法
2017/12/05 jQuery
理理Vue细节(推荐)
2019/04/16 Javascript
记录一次开发微信网页分享的步骤
2019/05/07 Javascript
vue动态路由:路由参数改变,视图不更新问题的解决
2019/11/05 Javascript
如何在面试中手写出javascript节流和防抖函数
2020/10/22 Javascript
[01:24]DOTA2上海特锦赛OG战队抵达 专车接机入驻总统套房
2016/02/23 DOTA
Python基类函数的重载与调用实例分析
2015/01/12 Python
Python数据结构之双向链表的定义与使用方法示例
2018/01/16 Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
2018/08/30 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
Python对excel的基本操作方法
2021/02/18 Python
ProBikeKit英国:在线公路自行车之家
2017/02/10 全球购物
sort命令的作用和用法
2012/11/04 面试题
国际政治个人自荐信范文
2013/11/26 职场文书
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
房屋财产继承协议书范本
2014/11/03 职场文书
2014年大学班长工作总结
2014/11/14 职场文书
.Net Core导入千万级数据至Mysql的步骤
2021/05/24 MySQL
HttpClient实现文件上传功能
2022/08/14 Java/Android