Promise拓展-async和await
1.什么是 async(其实就跟then方法是基本一致的)
async 顾名思义就是异步的意思,它是ES2017标准中引入的一种新函数,它是Generator函数的语法糖,它是作用是简化异步操作,使得异步操作更加简单
- async函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
//几乎跟then方法是一模一样
async function main1(){
//1. 如果返回值是一个非Promise类型的数据
return 'hello!';
}
async function main2(){
//2. 如果返回的是一个Promise对象(返回的是resolve类型)
return new Promise((resolve, reject) => {
resolve('OK');
});
}
async function main3(){
//3. 如果返回的是一个Promise对象(返回的是reject类型)
return new Promise((resolve, reject) => {
reject('Error');
});
}
async function main4(){
//4. 抛出异常
throw "Oh NO";
}
console.log(main1());//Promise {<fulfilled>: 'hello!'}
console.log(main2());//返回结果:状态为fulfilled的promise对象,返回值为OK
console.log(main3());//返回结果:状态为rejected的promise对象,返回值为Oh No
console.log(main4());//Promise {<rejected>: 'Oh NO'}
结果如下:
2.什么是 await ?
await顾名思义就是等待,它同样是ES2017中新引入的一种新表达式,用于嵌套async来使用,解决异步操作
- await 右侧的表达式一般为 promise 对象, 但也可以是其它的值(数字,字符串,布尔类型等,运算也可以)
- 如果表达式是 promise 对象, await 返回的是 promise 成功的值(切记是成功的值)
- 如果表达式是其它值, 直接将此值作为 await 的返回值(即右侧是什么我就返回什么)
注意:
- 1.await 必须写在 async 函数中, 但 async 函数中可以没有 await(就好比单相思)
- 2.如果 await 的 promise 失败了, 就会抛出异常, 则需要通过 try…catch 捕获处理
普及一下try-catch语法:
- try catch语句是JavaScript中一种处理异常的标准方式
try {
//可能会导致错误的代码
} catch (e(error的缩写)) {
//在错误发生时该如何进行处理
}
await 的使用demo
async function main1(){ |
结果如下:
3.util.promisify 函数用法的讲解
什么是 util.promisify?
- util.promisify是在node.js 8.x版本中新增的一个工具,用于将老式的Error first callback转换为Promise对象,让老项目改造变得更为轻松。
- 首先要解释一下这种工具大致的实现思路,因为在Node中异步回调有一个约定:Error first,也就是说回调函数中的第一个参数一定要是Error对象,其余参数才是正确时的数据。
作用:
- 传入一个错误优先的回调风格的函数(即形参要求错误优先(err,value)),返回一个promise版本
//引入 util 模块
const util = require('util');
//引入 fs 模块
const fs = require('fs');
//返回一个新的函数
// fs.readFile就是一个错误优先的函数方法(readFile('path',(err,data)=>{}))
let mineReadFile = util.promisify(fs.readFile);
// 直接读取Promise对象里面的value值
mineReadFile('./resource/content.txt').then(value=>{
console.log(value.toString());//转换buffer
});
结果如下:
async和await两者的结合使用大大方便了我们的开发(案例)
- 案例要求:读取resolve文件夹下面的三个文件:1.html 2.html和3.html
第一种方式:使用回调函数
//回调函数的方式(存在回调地狱,存在错误要每一层去做if-else判断,非常麻烦) |
第二种方式:async嵌套await
//没有回调地狱,并且整体简洁高效 |
结果如下(两者均一致):
案例展示:
- 要求:使用
async/await
来实现输出1 -> 2 -> 3
,但是2
要套一个延时函数(200ms
),结果要输出1 -> 2 -> 3
代码展示:
- 直接使用
await
限制异步操作:
async function test(){ |
结果展示:
由此可见:结果不尽如人意,那是因为
await
只能控制promise实例对象
,因此要想实现使用await
控制异步,就需要在给异步操作外面添加一层promise
代码如下:
async function test(){ |
- 结果展示:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0许可协议。转载请注明来自 肥林の仓库