# async函数

被称为JavaScript异步编程的最终解决方案。

# 基本用法

async声明函数内部有异步操作,且该函数返回一个Promise对象,可以进行和promise相关的所有操作。

await关键字必须在async函数内部调用。表示等待异步操作完成,再接着执行函数体内接下来的语句。

async函数的多种声明形式:

// 普通函数声明
async function wlk1(){};

// 函数表达式
const wlk2 = async function(){};

// 作为对象的方法
let obj = {
    async wlk3(){};
}
obj.wlk3().then(...);
                
// 作为Class的方法
class Space{
    constructor() {}
    async wlk4(){}
}

// 箭头函数
const wlk5 = async ()=>{};

# async

声明一个函数为异步函数,且该函数返回一个Promise对象。

async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f(){
    return "hello async!";
}
f().then(console.log);
// hello async!

async函数内部所有的await等待的结果返回后,才会执行then回调。如下:

async function f() {
    let res1 = await getFile1();
    let res2 = await getFile2();
    let res3 = await getFile3();
    return "all files got!";
}
f().then(console.log);

# await

正常情况下,await命令后面等待的是一个Promise对象的结果(resolvereject传递出来的值)。如果不是Promise对象结果,就直接返回对应的值。如下:

async function f(){
    return await "hello await!"   // 等同于 return "hello await!"
}
f().then(console.log);
// hello await!

async函数内部如果有一个promise对象变成reject状态,则该async函数会中断执行,立即返回,后面的代码不会被执行。如下:

async function f() {
    let res =  await Promise.reject('出错了');
    let res2 = await 123; // 不会被执行
    console.log(res,res2);// 不会被执行
}
f().catch(console.log);
// 出错了

如果希望一个async函数失败了,后面的async函数继续执行。可使用try...catch结构。如下:

async function f() {
    try{
        await Promise.reject('出错了');
    }catch(e){
        console.log(e)
    }
   return await Promise.resolve(111);
}
f().then(console.log);

// 出错了
// 111

注意以上代码的return关键字,必须存在,否则then回调函数的参数会为undefined。而reject时可以在不用return关键字。

提示

reject相当于throw一个Errorcatch语句就是模拟的try...catchcatch语句块。

async function f() {
    await Promise.resolve('没出错'); // 加入 return 关键字才会打印出值
}
f().then(console.log);
// undefined

async function f() {
  await Promise.reject('出错了');
}
f().catch(e => console.log(e))
// 出错了

# 使用注意点

第一点: await命令后面等待的是一个Promise对象的结果,状态有可能变为rejected,所以最好把await命令放在try...catch代码块中。

async function f() {
    try{
       let res =  await promiseResult();
    }catch (e) {
        console.log(e);
    }
}

// 另一种写法
async function f1() {
   let res = await promiseResult().catch(console.log);
}

警告

如果await后面等待的结果rejected,以上代码中的res就不会得到返回值,会为undefined。这点需要特别注意

第二点: 多个await命令后面的异步操作,如果不存在继发关系,最好让他们同时触发。

不推荐的写法:

let func1 = await getName();
let func2 = await getAge();
//以上两个异步操作是独立的,互不依赖,如果这样写成继发关系,会比较耗时。

推荐写法(同时触发):

// 写法一 : 利用 Promise.all()。
let [func1,func2] = await Promise.all([getName(),getAge()]);

// 写法二 : 利用 await 等待已执行函数结果
let func1Res = getName();
let func2Res = getAge();
let func1 = await func1Res;
let func2 = await func2Res;

第三点: await命令只能用在async函数中,如果用在普通函数中,会报错。

作者:王龙楷; 标签:原创; 提交时间: 5/20/2020, 9:35:22 AM