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还原含有rowspan、colspan的table的实现方法
Feb 10 Javascript
JavaScript实现在标题栏上显示当前日期的方法
Mar 19 Javascript
jQuery同步提交示例代码
Dec 12 Javascript
设置jQueryUI DatePicker默认语言为中文
Jun 04 Javascript
原生js代码实现图片放大境效果
Oct 30 Javascript
HTML5+jQuery实现搜索智能匹配功能
Mar 24 jQuery
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 Javascript
Mongoose实现虚拟字段查询的方法详解
Aug 15 Javascript
浅谈react前后端同构渲染
Sep 20 Javascript
js中如何完美的解析数据
Mar 18 Javascript
JS可断点续传文件上传实现代码解析
Jul 30 Javascript
JS前端基于canvas给图片添加水印
Nov 11 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 $_SERVER windows系统与linux系统下的区别说明
2014/02/14 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
PHP关于htmlspecialchars、strip_tags、addslashes的解释
2014/07/04 PHP
php中单个数据库字段多列显示(单字段分页、横向输出)
2014/07/28 PHP
ThinkPHP 404页面的设置方法
2015/01/14 PHP
php简单生成随机数的方法
2015/07/30 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
javaScript call 函数的用法说明
2010/04/09 Javascript
学习面向对象之面向对象的基本概念:对象和其他基本要素
2010/11/30 Javascript
关于img的href和src取变量及赋值的方法
2014/04/28 Javascript
纯js模拟div层弹性运动的方法
2015/07/27 Javascript
jquery+ajax实现注册实时验证实例详解
2015/12/08 Javascript
javascript中JSON.parse()与eval()解析json的区别
2016/05/19 Javascript
用jQuery向div中添加Html文本内容的简单实现
2016/07/13 Javascript
jQuery扩展_动力节点Java学院整理
2017/07/05 jQuery
JavaScript基于面向对象实现的猜拳游戏
2018/01/03 Javascript
Vue如何实现响应式系统
2018/07/11 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
vue设置动态请求地址的例子
2019/11/01 Javascript
JavaScript基于用户照片姓名生成海报
2020/05/29 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
python学习 流程控制语句详解
2016/06/01 Python
python实现斐波那契数列的方法示例
2017/01/12 Python
Python使用zip合并相邻列表项的方法示例
2018/03/17 Python
浅析python继承与多重继承
2018/09/13 Python
python requests 库请求带有文件参数的接口实例
2019/01/03 Python
为什么黑客都用python(123个黑客必备的Python工具)
2020/01/31 Python
CSS3动画之流彩文字效果+图片模糊效果+边框伸展效果实现代码合集
2017/08/18 HTML / CSS
RealTek面试题
2016/06/28 面试题
英语道歉信范文
2014/01/09 职场文书
我的求职择业计划书
2014/04/04 职场文书
给校长的建议书300字
2014/05/16 职场文书
党的群众路线对照检查材料
2014/09/22 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
文明旅游倡议书
2015/04/28 职场文书