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 面向对象技术基础教程
Mar 03 Javascript
将json对象转换为字符串的方法
Feb 20 Javascript
JS对文本框值的判断示例
Mar 10 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
Apr 14 Javascript
js如何判断用户是否是用微信浏览器
Jun 05 Javascript
JS延时器提示框的应用实例代码解析
Apr 27 Javascript
javascript实现文字无缝滚动
Dec 27 Javascript
浅谈React中组件间抽象
Jan 27 Javascript
对Vue.js之事件的绑定(v-on: 或者 @ )详解
Sep 15 Javascript
React Native中Mobx的使用方法详解
Dec 04 Javascript
vue的for循环使用方法
Feb 12 Javascript
手写Vue弹窗Modal的实现代码
Sep 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 常用的header头部定义汇总
2015/06/19 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
Laravel如何自定义command命令浅析
2019/03/23 PHP
laravel 输出最后执行sql 附:whereIn的使用方法
2019/10/10 PHP
Thinkphp框架+Layui实现图片/文件上传功能分析
2020/02/07 PHP
小型js框架veryide.librar源代码
2009/03/05 Javascript
从URL中提取参数与将对象转换为URL查询参数的实现代码
2012/01/12 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
2012/12/15 Javascript
js函数获取html中className所在的内容并去除标签
2013/09/08 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
javascript 动态创建表格
2015/01/08 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
2015/12/12 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
JS中对数组元素进行增删改移的方法总结
2016/12/15 Javascript
解决Angular.Js与Django标签冲突的方案
2016/12/20 Javascript
原生ajax处理json格式数据的实例代码
2016/12/25 Javascript
react-router实现跳转传值的方法示例
2017/05/27 Javascript
Javascript中将变量转换为字符串的三种方法
2017/09/19 Javascript
JavaScript实现PC端横向轮播图
2020/02/07 Javascript
[03:46]DAC趣味视频-中文考试.mp4
2017/04/02 DOTA
python批量提交沙箱问题实例
2014/10/08 Python
python实现抖音视频批量下载
2018/06/20 Python
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
python:按行读入,排序然后输出的方法
2019/07/20 Python
澳大利亚新奇小玩意网站:Yellow Octopus
2017/12/28 全球购物
欧尚俄罗斯网上超市:Auchan俄罗斯
2018/05/03 全球购物
Beach Bunny Swimwear官网:设计师泳装和性感比基尼
2019/03/13 全球购物
如何编写优秀的食品项目创业计划书
2014/01/23 职场文书
医学院毕业生自荐信范文
2014/03/06 职场文书
工作决心书
2014/03/11 职场文书
感情真挚的毕业生求职信
2014/07/19 职场文书
小学领导班子对照材料
2014/08/23 职场文书
2014年实习期工作总结
2014/11/27 职场文书
优秀班主任申报材料
2014/12/16 职场文书
施工安全协议书
2016/03/22 职场文书
如何书写邀请函?
2019/06/24 职场文书