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 相关文章推荐
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
May 08 Javascript
Javascript 原型和继承(Prototypes and Inheritance)
Apr 01 Javascript
JS 获取滚动条高度示例代码
Oct 24 Javascript
jquery滚动条插件jScrollPane的使用介绍
Nov 08 Javascript
node.js 开发指南 ? Node.js 连接 MySQL 并进行数据库操作
Jul 29 Javascript
使用jQuery将多条数据插入模态框的实现代码
Oct 08 Javascript
Javascript字符串浏览器兼容问题分析
Dec 01 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
Sep 01 Javascript
JavaScript下拉菜单功能实例代码
Mar 01 Javascript
使用vue和datatables进行表格的服务器端分页实例代码
Jun 07 Javascript
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
Jun 05 Javascript
Node.js API详解之 V8模块用法实例分析
Jun 05 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中date()日期函数有关参数整理
2011/07/19 PHP
php递归函数怎么用才有效
2018/02/24 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
在JavaScript中遭遇级联表达式陷阱
2007/03/08 Javascript
document.designMode的功能与使用方法介绍
2007/11/22 Javascript
JS函数实现动态添加CSS样式表文件
2012/12/15 Javascript
运行Node.js的IIS扩展iisnode安装配置笔记
2015/03/02 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
2016/01/06 Javascript
Jquery实现的简单轮播效果【附实例】
2016/04/19 Javascript
浅谈String.valueOf()方法的使用
2016/06/06 Javascript
关于javascript事件响应的基础语法总结(必看篇)
2016/12/26 Javascript
Angularjs中使用layDate日期控件示例
2017/01/11 Javascript
js阻止移动端页面滚动的两种方法
2017/01/25 Javascript
Vue.js学习笔记之常用模板语法详解
2017/07/25 Javascript
Windows安装Node.js报错:2503、2502的解决方法
2017/10/25 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
vue 双向数据绑定的实现学习之监听器的实现方法
2018/11/30 Javascript
vue插件mescroll.js实现移动端上拉加载和下拉刷新
2019/03/07 Javascript
vue实现吸顶、锚点和滚动高亮按钮效果
2019/10/21 Javascript
Node.js操作MongoDB数据库实例分析
2020/01/19 Javascript
[02:03]完美世界DOTA2联赛10月30日赛事集锦
2020/10/31 DOTA
Python实现在tkinter中使用matplotlib绘制图形的方法示例
2018/01/18 Python
对Python中range()函数和list的比较
2018/04/19 Python
Python单向链表和双向链表原理与用法实例详解
2018/08/31 Python
django使用haystack调用Elasticsearch实现索引搜索
2019/07/24 Python
python实现统计代码行数的小工具
2019/09/19 Python
python3下pygame如何实现显示中文
2020/01/11 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
python3 中时间戳、时间、日期的转换和加减操作
2020/07/14 Python
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
道路建设实施方案
2014/03/18 职场文书
1亿有多大教学反思
2014/05/01 职场文书
大学生档案自我鉴定(2篇)
2014/10/14 职场文书
2015年节能减排工作总结
2015/05/14 职场文书
酒吧七夕情人节宣传语
2015/11/24 职场文书
详解pytorch创建tensor函数
2022/03/22 Python