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小玩意 几个属性相加不能超过一个特定值.
Sep 29 Javascript
js采用map取到id集合组并且实现点击一行选中一行
Dec 16 Javascript
window.open打开页面居中显示的示例代码
Dec 27 Javascript
jQuery filter函数使用方法
May 19 Javascript
js正则表达式匹配数字字母下划线等
Apr 14 Javascript
jQuery满屏焦点图左右滚动特效代码分享
Sep 07 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
Apr 26 Javascript
JS排序之快速排序详解
Apr 08 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
Jul 09 Javascript
JavaScript实现拖拽功能
Feb 11 Javascript
详解JS深拷贝与浅拷贝
Aug 04 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
详解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/07/15 PHP
PHP curl模拟登录带验证码的网站
2015/11/30 PHP
可缩放Reloaded-一个针对可缩放元素的复用组件
2007/03/10 Javascript
JavaScript内核之基本概念
2011/10/21 Javascript
利用JavaScript实现新闻滚动效果(实例代码)
2013/11/27 Javascript
jQuery中验证表单提交方式及序列化表单内容的实现
2014/01/06 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
2015/08/03 Javascript
一次记住JavaScript的6个正则表达式方法
2018/02/22 Javascript
element-ui 限制日期选择的方法(datepicker)
2018/05/16 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
解决vue中修改export default中脚本报一大堆错的问题
2018/08/27 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
微信小程序自定义扫码功能界面的实现代码
2020/07/02 Javascript
js实现数字跳动到指定数字
2020/08/25 Javascript
vue全局使用axios的操作
2020/09/08 Javascript
vue radio单选框,获取当前项(每一项)的value值操作
2020/09/10 Javascript
用Python编写web API的教程
2015/04/30 Python
Python多线程下载文件的方法
2015/07/10 Python
通过Python实现自动填写调查问卷
2017/09/06 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
详解python函数传参是传值还是传引用
2018/01/16 Python
Python生成短uuid的方法实例详解
2018/05/29 Python
对python的unittest架构公共参数token提取方法详解
2018/12/17 Python
详解Django中CBV(Class Base Views)模型源码分析
2019/02/25 Python
Django接收自定义http header过程详解
2019/08/23 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
英国买鞋网站:Charles Clinkard
2019/11/14 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
酒店值班经理的工作职责范本
2014/02/18 职场文书
法人代表身份证明书及授权委托书
2014/09/16 职场文书
校运会新闻稿
2015/07/17 职场文书
公司酒会致辞
2015/07/30 职场文书
《我在为谁工作》:工作的质量往往决定生活的质量
2019/12/27 职场文书
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android
Android自定义scrollview实现回弹效果
2022/04/01 Java/Android