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利用Array.splice实现Array的insert/remove
Jan 13 Javascript
FF IE兼容性的修改小结
Sep 02 Javascript
jQuery 获取对象 基本选择与层级
May 31 Javascript
模拟select的代码
Oct 19 Javascript
JavaScript与HTML的结合方法详解
Nov 23 Javascript
jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
Mar 14 Javascript
Bootstrap模态框使用详解
Feb 15 Javascript
Bootstrap面板(Panels)的简单实现代码
Mar 17 Javascript
jQuery插件HighCharts绘制简单2D折线图效果示例【附demo源码】
Mar 21 jQuery
JavaScript数据结构之优先队列与循环队列实例详解
Oct 27 Javascript
vue中使用protobuf的过程记录
Oct 26 Javascript
webpack优化之代码分割与公共代码提取详解
Nov 22 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生成月历代码
2007/06/14 PHP
两个开源的Php输出Excel文件类
2010/02/08 PHP
浅析php创建者模式
2014/11/25 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
js鼠标左右键 键盘值小结
2010/06/11 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
JavaScript学习笔记(一) js基本语法
2011/10/25 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
javascript屏蔽右键代码
2014/05/15 Javascript
js查找节点的方法小结
2015/01/13 Javascript
举例简介AngularJS的内部语言环境
2015/06/17 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
在微信小程序里使用watch和computed的方法
2018/08/02 Javascript
让webpack+vue-cil项目不再自动打开浏览器的方法
2018/09/27 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
JavaScript运动原理基础知识详解
2020/04/02 Javascript
JS替换字符串中指定位置的字符(多种方法)
2020/05/28 Javascript
在vue中使用防抖函数组件操作
2020/07/26 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
Python读写Excel文件的实例
2013/11/01 Python
从源码解析Python的Flask框架中request对象的用法
2016/06/02 Python
Python中内置的日志模块logging用法详解
2016/07/12 Python
安装Python的教程-Windows
2017/07/22 Python
python difflib模块示例讲解
2017/09/13 Python
Python3中条件控制、循环与函数的简易教程
2017/11/21 Python
python实现基于SVM手写数字识别功能
2020/05/27 Python
一个可以套路别人的python小程序实例代码
2019/04/09 Python
美国领先的男士和女士内衣购物网站:Freshpair
2019/02/25 全球购物
新闻学毕业生自荐信
2013/11/15 职场文书
大学生实习感言
2014/01/16 职场文书
人力资源经理的岗位职责范本
2014/02/28 职场文书
爱心捐助倡议书
2014/05/19 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书