【ES6】异步操作和async函数
【ES6】异步操作和async函数
- 一、基本概念
- 二、回调函数
- 三、Promise
- 四、async函数
- 查看更多ES6教学文章:
- 参考文献
引言:ES6新增的Generato、Promise、async都与异步编程有关。这里我们讲述async函数和相关的异步操作。 |
异步编程对于JavaScript语言极为重要。JavaScript 只有一个线程,如果没有异步编程, 得卡死,基本没法用。
ES6诞生前,异步编程的方法大概有下面4种:
回调函数
事件监听
发布/订阅
Promise对象
ES6将JavaScript异步编程带人了一一个全新的阶段,ES7 中的async函数更是给出了异步编程。
一、基本概念
所谓“异步”,简单说就是一个任务分成两段,先执行第一段, 然后转而执行其他任务,等做好准备再回过头执行第二段。
比如,有一个任务是读取文件进行处理,任务的第一段 是向操作系统发出请求,要求读取文件。然后,程序执行其他任务,等到操作系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫作异步。
相应地,连续的执行就叫作同步。由于是连续执行,不能插人其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着。
二、回调函数
JavaScript语言对异步编程的实现就是回调函数。所谓回调函数,就是把任务的第二段单独写在一个函数中,等到重新执行该任务时直接调用这个函数。其英文名字“ callback"直译过来就是“重新调用”。
读取文件进行处理是这样写的。
fs.readFile( 'D://data.txt', function (err, data) {if (err) throw err;console.log(data);
});
上面的代码中,readFiLe函数的第二个参数就是回调函数,也就是任务的第二段。 等到操作系统返回了文件以后,回调函数才会执行。
三、Promise
回调函数本身并没有问题,问题出在多个回调函数嵌套。假定读取A文件后再读取B文件,代码如下。
fs.readFile(fileA, function (err, data)fs.readFile(fileB, function (err, data)// ...});
});
不难想象,如果依次读取多个文件,就会出现多重嵌套。代码不是纵向发展,而是横向发展,很快就会乱成一团,无法管理。这种情况就称为“回调函数噩梦”( callback hell )。
Promise就是为了解决这个问题而提出的。它不是新的语法功能,而是一种新的写法, 允许将回调函数的横向加载改成纵向加载。采用Promise,连续读取多个文件的写法如下。
var readFile = require( 'fs-readfile-promise );readFile(fileA)
.then(function(data){console.log(data.toString());
})
.then(function(){return readFile(fileB);
})
.then(function(data){console.log(data.toString());
})
.catch(function(err) {console.log(err);
});
上面的代码中使用了fs-readfile-promise模块,其作用是返回一个Pomise版本的readFile函数。Promise提供then方法加载回调函数,catch方法捕捉执行过程中抛出的错误。
可以看到,Pomise 的写法只是回调函数的改进,使用then方法后,异步任务的两段执行看得更清楚了,除此以外并无新意。
Pomise的最大问题是代码冗余。原来的任务被Promise 包装了一下,不管什么操作,一眼看去都是一堆then,原来的语义变得很不清楚。
四、async函数
这里我提供一个我经常使用的根据函数:时间延迟函数,在test函数中,可以间隔1秒在控制台打印“world”字符。
function sleep(ms){//时间延迟函数return new Promise(resolve =>setTimeout(resolve,ms))}async function test() {console.log('Hello')await sleep(1000)console.log('world!')}
ES7提供了async函数,使得异步操作变得更加方便。async函数就是Generator函数的语法糖。
一比较就会发现,async两数就是将Generator丽数的星号(*)替换成async,将yield替换成await,仅此而已。
async函数对Generator函数的改进体现在以下4点。
1.内置执行器。Generator函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行与普通函数一模一样,只要一行。
2. async函数会自动执行,输出最后结果。完全不像Generator函数,需要调用next方法,或者用co模块,才能得到真正执行,从而得到最终结果。
3. 更好的语义。async和wait比起星号和yield,语义更清楚。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
4.更广的适用性。co模块约定,yield命令后面只能是Thunk函数或Promise对象,而async图数的await命令后面可以是Promise对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
5.返回值是Promise。async函数的返回值是Promise对象,这比Generator函数的返回值是Iterator对象方便多了。
进一步说,async函数完全可以看作由多个异步操作包装成的一个Promise对象,而await命令就是内部then命令的语法糖。
查看更多ES6教学文章:
1. 【ES6】let与const 详解
2. 【ES6】变量的解构赋值
3. 【ES6】字符串的拓展
4. 【ES6】正则表达式的拓展
5. 【ES6】数值的拓展
6. 【ES6】数组的拓展
7. 【ES6】函数的拓展
8. 【ES6】对象的拓展
9. 【ES6】JS第7种数据类型:Symbol
10. 【ES6】Proxy对象
11. 【ES6】JS的Set和Map数据结构
12. 【ES6】Generator函数详解
13. 【ES6】Promise对象详解
14. 【ES6】异步操作和async函数
15. 【ES6】JS类的用法class
16. 【ES6】Module模块详解
17. 【ES6】ES6编程规范 编程风格
参考文献
阮一峰 《ES6标准入门(第2版)》
【ES6】异步操作和async函数相关推荐
- es6 什么是async函数
什么是async函数 ES2017 标准引入了 async函数,使得异步操作变得更加方便. async函数是什么?一句话,它就是 Generator函数的语法糖. 前文有一个 Generator函数, ...
- 阮一峰老师的ES6入门:async 函数
async 函数 1. 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 Gener ...
- async 函数 ajax,Async 函数的使用及简单实现
解决回调地狱的异步操作,Async 函数是终极办法,但了解生成器和 Promise 有助于理解 Async 函数原理.由于内容较多,分三部分进行,这是第三部分,介绍 Async 函数相关.第一部分介绍 ...
- es6 async函数实例:按顺序完成异步操作
async函数实例:按顺序完成异步操作 实际开发中,经常遇到一组异步操作,需要按照顺序完成.比如,依次远程读取一组 URL,然后按照读取的顺序输出结果. ES6 Promise 的写法如下. func ...
- JS异步操作新体验之 async函数
1.初识 async 函数 ES6中提供了两个很好的解决异步操作的方案 Promise 和 Generator,ES2017标准中引入的 async 函数就是建立在 Promise 和 Generat ...
- es6 async函数的异步迭代器
async函数的异步迭代器 <迭代器>一章说过,Iterator 接口是一种数据遍历的协议,只要调用迭代器对象的next方法,就会得到一个对象,表示当前遍历指针所在的那个位置的信息.nex ...
- es6 async函数的语法
async函数的语法 async函数的语法规则总体上比较简单,难点是错误处理机制. 返回 Promise 对象 async函数返回一个 Promise 对象. async函数内部return语句返回的 ...
- es6 async函数的基本用法
async函数的基本用法 async函数返回一个 Promise 对象,可以使用then方法添加回调函数.当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句 ...
- ES6学习(十)—async 函数
ES6学习(十)-async 函数 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. 概念:真正意义上去解决异步回调的问题,同步流程表达异步操作 本质: Generator 函数 ...
最新文章
- SQL SERVER 2012启动失败 because upgrade step 'SSIS_hotfix_install.sql' 失败
- 如何初始化一个vue项目
- OpenShift 4 Tekton - Tekton实现包含Gogs+SonaQube+Nexus+Report+WebHook的Pipeline
- 在WPF 4.5中跨线程更新集合
- android 实现表格横向混动_凌派锐·混动:技术赋能下的越级表现
- [运动规划算法]Minimum Snap轨迹规划
- big mac sur 免驱显卡_macOS Big Sur 系统原生显卡驱动信息表
- LM1875功放板设计实例
- Codeforces 855G Harry Vs Voldemort 边双连通分量+并查集
- 【音视频基础】视频基础理论
- 利用eNSP进行VPLS仿真实验
- 如果不能产生价值,阅读便毫无意义
- python程序编程千分符号怎么输入_Excel表格中怎么输入千分之一符号
- ERNIE,ERNIE2.0,Transformer-XL,XLNET
- jsp mysql留言板制作_Jsp+mysql 制作留言板
- STM32的HAL库知识总结
- 浅尝UI自动化之Airtest实践
- Vscode下jupyter无法显示plot画图,并显示<Figure size 640x480 with 1 Axes>问题解决
- 【GD32开发】一、GD32F103 TIMER0 PWM死区时间计算
- Dirichlet 理解
热门文章
- np.reshape()
- JS 中的 Map,Set 和 iterable
- 基于生成式深度学习方法设计潜在2019-nCoV蛋白酶抑制剂
- Locality Sensitive Hashing(局部敏感哈希)
- Networkx-cycle
- 舵机任意角度程序_真香!!!飞特发布性价比超高的19kg磁编码360°双轴串口总线舵机STS3215...
- FastQC结果解读
- 视频演示:高颜值免费在线绘图ImageGP
- QIIME 2用户文档. 15进行纵向和成对样本比较q2-longitudinal(2018.11)
- R语言ggplot2可视化:可视化华夫饼图(Waffle Chart) 、华夫饼图可以直观地显示完成度(百分比)或者部分占整体的比例、华夫饼图适合于同类型指标的比较(Waffle Chart)