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 相关文章推荐
Web 前端设计模式--Dom重构 提高显示性能
Oct 22 Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
Oct 29 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
Nov 18 Javascript
JQuery教学之性能优化
May 14 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
Sep 04 Javascript
基于KO+BootStrap+MVC实现的分页控件代码分享
Nov 07 Javascript
jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
May 26 jQuery
荐书|您有一份JavaScript书单待签收
Jul 21 Javascript
express如何使用session与cookie的方法
Jan 30 Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
Apr 27 Javascript
nuxt.js 在middleware(中间件)中实现路由鉴权操作
Nov 06 Javascript
vue中activated的用法
Jan 03 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+mysql写的留言本
2006/10/09 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
Ajax+PHP实现的模拟进度条功能示例
2019/02/11 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
php中的依赖注入实例详解
2019/08/14 PHP
jQuery创建插件的代码分析
2011/04/14 Javascript
基于jquery的当鼠标滚轮到最底端继续加载新数据思路分享(多用于微博、空间、论坛 )
2011/10/10 Javascript
jQuery实现随意改变div任意属性的名称和值(部分原生js实现)
2013/05/28 Javascript
jQuery ajax serialize() 方法使用示例
2014/11/02 Javascript
了解Javascript的模块化开发
2015/03/02 Javascript
jQuery子窗体取得父窗体元素的方法
2015/05/11 Javascript
JavaScript访问字符串中单个字符的两种方法
2015/07/03 Javascript
12种JavaScript常用的MVC框架比较分析
2015/11/16 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
详解vue axios中文文档
2017/09/12 Javascript
轻量级JS Cookie插件js-cookie的使用方法
2018/03/22 Javascript
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
Python信息抽取之乱码解决办法
2017/06/29 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
Weekendesk意大利:探索多种引人入胜的周末主题
2016/10/14 全球购物
Marc O’Polo俄罗斯官方在线商店:德国高端时尚品牌
2019/12/26 全球购物
实习生个人找工作的自我评价
2013/10/30 职场文书
商务助理岗位职责
2013/11/13 职场文书
园林资料员岗位职责
2013/12/30 职场文书
师范毕业生自我鉴定
2014/01/15 职场文书
个人自我评价范文
2014/02/05 职场文书
高一数学教学反思
2014/02/07 职场文书
中班中秋节活动反思
2014/02/18 职场文书
道路建设实施方案
2014/03/18 职场文书
家教广告词
2014/03/19 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
2014年体检中心工作总结
2014/12/23 职场文书
信仰观后感
2015/06/03 职场文书
保护地球的宣传语
2015/07/13 职场文书
MongoDB使用场景总结
2022/02/24 MongoDB
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
2022/04/24 Java/Android