首页 > 其他分享 >【ES6】异步操作和async函数

【ES6】异步操作和async函数

时间:2023-01-16 17:33:29浏览次数:33  
标签:function ES6 函数 异步 Promise 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版)》


标签:function,ES6,函数,异步,Promise,async
From: https://blog.51cto.com/u_15942590/6010585

相关文章

  • 【ES6】Generator函数详解
    【ES6】Generator函数详解​​一、Generator函数简介​​​​基本概念​​​​函数写法​​​​yield关键字介绍​​​​二、next方法的参数​​​​三、for...of循环​​​......
  • 【ES6】Promise对象详解
    【ES6】Promise对象详解​​一、Promise对象的含义​​​​二、Promise对象的用法​​​​三、Promise对象的几个应用【重点】​​​​1、时间延迟函数​​​​2、图片异步......
  • 【ES6】JS的Set和Map数据结构
    【ES6】JS的Set和Map数据结构​​一、Set​​​​1、基本用法​​​​2、4种操作方法​​​​3、4种遍历方法​​​​4、Set的应用​​​​1)Set转化为数组​​​​2)去除数组......
  • 【ES6】Proxy对象
    【ES6】Proxy对象​​一、Proxy的基本用法​​​​二、Proxy示例的方法​​​​1)get()​​​​2)set()​​​​3)apply()​​​​查看更多ES6教学文章:​​​​参考文献​​引......
  • 【ES6】JS第7种数据类型:Symbol
    【ES6】JS第7种数据类型:Symbol​​一、Symbol的由来​​​​二、Symbol的涵义​​​​三、Symbol的判等​​​​四、Symbol的运算与转化​​​​查看更多ES6教学文章:​​​......
  • 【ES6】对象的拓展
    【ES6】对象的拓展​​一、对象的两种表示法【掌握】​​​​1)简洁表示法​​​​2)属性名表达式法​​​​二、Object.is()【了解】​​​​三、Object.assign()【了解】​......
  • JavaScript async/await 的用法以及它与 Promise 的区别
    async/await是JavaScript中的语法糖,用于简化异步代码的编写。它允许你在异步代码中使用同步风格的语法,使代码更易于阅读和维护。用法:使用关键字async声明一个异步......
  • c#利用异步方法去模拟多线程处理业务
    一个巧妙的设计原理:利用async标识方法执行异步处理List<long>listIds=newList<long>();//业务任务:假设处理这个列表的任务objectlockObj=newobject......
  • ES6+ 字符串的扩展
    1.前言由于历史原因,在JavaScript创建之初,市面上的编码方式还是很混乱的,JavaScript在创建之初,使用的是1990年公布的UCS-2的编码方法,使用2个字节表示1个字符,那时......
  • ES6+ includes()
    1.前言字符串查找一直都是程序中的常用操作,在ES5中查找一个字符串是否包含另一个字符串,一般有两种思维。一是使用正则的方式来匹配,二是使用ES5的方式,如indexOf、lastI......