es6中async和await-使用

Posted JackieDYH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es6中async和await-使用相关的知识,希望对你有一定的参考价值。

nodeJs,fs.readFile实例演示,用三种方法读取文件

  1. promise
  2. genrator
  3. async

(1)promise方法

const fs = require('fs');
//promise方法
//简单封装  fs封装成一个promise
const readFile = function (fileName){
    return new Promise((resolve, reject) =>{
        fs.readFile(fileName, (err, data) =>{
            if(err) reject(err);//如果失败调用reject
            resolve(data);//如果成功
        });
    });
}
//promise
readFile('data/a.txt').then(res=>{
    console.log(res.toString());//aaaaaaa
    return readFile('data/b.txt');
}).then(res=>{
    console.log(res.toString());//bbbbbb
    return readFile('data/c.txt');
}).then(res=>{
    console.log(res.toString());//cccccc
})//和请求是同样的,但不用再像往常那样再一层套一层

(2)generator方法

优势在于请求统一放在定义的方法里,不用在调用方法的then里面写,代码优雅度较高。缺点是和promise一样必须一步步手动调用。对于解决异步问题来说是个过渡期产品,有了async就不需要用了。

//generator,优势在于请求统一放在定义的方法里,不用在调用方法的then里面写
function *gen(){
  yield  readFile('data/a.txt');
  yield  readFile('data/b.txt');
  yield  readFile('data/c.txt');
}
let g1=gen();
g1.next().value.then(res=>{
  console.log(res.toString());//aaaaaaa
  return g1.next().value;
}).then(res=>{
  console.log(res.toString());//bbbbbb
  return g1.next().value;
}).then(res=>{
  console.log(res.toString());//cccccc
})

(3)async方法,配合await使用

async function fn(){
  let f1 = await readFile('data/a.txt');
  let f2 = await readFile('data/b.txt');
  let f3 = await readFile('data/c.txt');
  console.log(f1.toString());
  console.log(f2.toString());
  console.log(f3.toString());
}
fn();
//也可以像下面这么用
async function fn(){
    let [a,b,c] = await Promise.all([
        readFile('data/a.txt'),
        readFile('data/b.txt'),
        readFile('data/c.txt'),
    ]);
    console.log(a.toString());
    console.log(b.toString());
    console.log(c.toString());
}
fn();

语法:

async function fn(){  //表示异步,这个函数里面有异步任务
    let result = await  xxx //表示后面结果需要等待数据读取完后执行    
}

async特点:

  1. await只能放到async函数中
  2. 相比genrator语义化更强
  3. await后面可以是promise对象,也可以是数字、字符串、布尔
  4. async函数返回的是一个promise对象
  5. 只要await语句后面Promise状态变成 reject, 那么整个async函数会中断执行
//不放await
async function fn(){
    return 'welcome';
}
console.log(fn());//Promise {<resolved>: "welcome"}
  fn().then(res=>{
    console.log(res);//welcome
});

如何抛出错误

async function fn1(){
    throw new Error('Error出错了');
  }

  fn1().then(res=>{
    console.log(res);//没走这个
  }, err =>{//捕获错误
    console.log(err);//Error: Error出错了
  })

//等同于下述方法,但catch用得更多

async function fn2(){
    throw new Error('Error出错了');
}

fn2().then(res=>{
    console.log(res);//不执行
  }).catch(err=>{
    console.log(err);//Error: Error出错了
});

若出错,成功方法便中断,无法执行

async function fn3(){
    let a = await Promise.resolve('success');
    console.log(a);//success
    await Promise.reject('出现问题了');
}
fn3().then(res=>{
    console.log(res);//无意义
}).catch(err=>{
    console.log(err);//出现问题了
})

如何解决async函数中抛出错误,影响后续代码:
a). 将如下代码

try{
}catch(e){
//
}
async function fn4(){
    try{
        await Promise.reject('出现问题了');
    }catch(e){    
    }
    //下述仍可执行
    let a = await Promise.resolve('success');
    console.log(a);//success
}
fn4().then(res=>{
    console.log(res);
    }).catch(err=>{
    console.log(err);
})

b). promise本身catch

async function fn5(){
    await Promise.reject('出现问题了').catch(err=>{
        console.log(err);//出现问题了
    });
    //下述仍可执行
    let a = await Promise.resolve('success');
    console.log(a);//success
}

fn5().then(res=>{
    console.log(res);
});

个人建议大家:只要有await都try catch

async function fn1(){
    try {
        let f1 = await readFile('data/a.txt');
        let f2 = await readFile('data/b.txt');
        let f3 = await readFile('data/c.txt');
    }catch (e) {
}
    console.log(f1.toString());
    console.log(f2.toString());
    console.log(f3.toString());
}
console.log(fn1());

以上是关于es6中async和await-使用的主要内容,如果未能解决你的问题,请参考以下文章

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

es6之 async await 使用小计

在 ES6 React .JS 中使用 Async/Await

JavaScript的ES6中async&&await的简单使用以及介绍

es6 async与await实战