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 相关文章推荐
基于jquery的checkbox下拉框插件代码
Jun 25 Javascript
利用jQuery简单实现产品展示图片左右滚动功能(示例代码)
Jan 02 Javascript
JQuery中操作Css样式的方法
Feb 12 Javascript
js实现缓冲运动效果的方法
Apr 10 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
Jun 23 Javascript
AngularJS中$watch和$timeout的使用示例
Sep 20 Javascript
node.js缺少mysql模块运行报错的解决方法
Nov 13 Javascript
JS变量及其作用域
Mar 29 Javascript
创建echart多个联动的示例代码
Nov 23 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
Dec 29 Javascript
详解wepy开发小程序踩过的坑(小结)
May 22 Javascript
jquery轻量级数字动画插件countUp.js使用详解
Oct 17 jQuery
详解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获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
Yii控制器中filter过滤器用法分析
2016/07/15 PHP
Mac系统完美安装PHP7详细教程
2017/06/06 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
php调用云片网接口发送短信的实现方法
2017/10/25 PHP
asp批量修改记录的代码
2008/06/25 Javascript
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
cloudgamer出品ImageZoom 图片放大效果
2010/04/01 Javascript
利用js正则表达式验证手机号,email地址,邮政编码
2014/01/23 Javascript
使用CoffeeScrip优美方式编写javascript代码
2015/10/28 Javascript
jQuery自适应轮播图插件Swiper用法示例
2016/08/24 Javascript
学习vue.js中class与style绑定
2016/12/03 Javascript
微信小程序开发之大转盘 仿天猫超市抽奖实例
2016/12/08 Javascript
利用PM2部署node.js项目的方法教程
2017/05/10 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
vue本地打开build后生成的dist文件夹index.html问题
2019/09/04 Javascript
VUEX采坑之路之获取不到$store的解决方法
2019/11/08 Javascript
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
Python实现图片识别加翻译功能
2019/12/26 Python
Tensorflow限制CPU个数实例
2020/02/06 Python
Python devel安装失败问题解决方案
2020/06/09 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
python自动提取文本中的时间(包含中文日期)
2020/08/31 Python
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
开普敦通行证:Cape Town Pass
2019/07/18 全球购物
美国排名第一的葡萄酒俱乐部:Firstleaf Wine Club
2020/01/02 全球购物
递归实现回文判断(如:abcdedbca就是回文,判断一个面试者对递归理解的简单程序)
2013/04/28 面试题
JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?
2015/10/22 面试题
信息专业本科生个人的自我评价
2013/10/28 职场文书
小区门卫值班制度
2014/01/24 职场文书
党的群众路线教育实践活动个人承诺书
2014/05/22 职场文书
教师自查自纠工作情况报告
2014/10/29 职场文书
遗嘱继承权公证书
2015/01/26 职场文书
人生感悟经典句子
2019/08/20 职场文书