async和await搭配使用

2019-06-24  本文已影响0人  lulu_c

async

异步关键字,一般我们把这个关键字写在函数前,用于表示函数是一个异步函数, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行。

声明async函数的几个方法:

async function A(){}
let A = async function(){}
let A = async ()=>{}

异步函数调用也跟普通函数调用一样

async function A(){}
console.log(A());
console.log('虽然在后面,但是我先执行');
结果

我们可以看到,异步函数是不会阻塞下面代码的执行,并且异步函数返回了一个promise 对象,promise 对象是可以返回值和抛出错误的:

async function A(val){
    if (val) {
        return '123'
    } else {
        throw '错误'
    }
}
console.log(A(true));
console.log(A(false));
结果

再使用then和catch捕获返回值和错误信息。

await

等待关键字,意思是等待,等待后面的表达式执行完再继续执行下面的代码,这个作用的好处就是能大大减少回调地狱。后面可以放置任何表达式,但是更多的是放一个返回promise 对象的表达式。注意await 关键字只能放到async 函数里面。

举个例子,有个场景,需要调用a方法调取接口数据,等到获取数据之后再执行b方法,如果这时候不使用await,那就是需要编写回调方法,当我们再多几步这样的操作就很容易陷入回调地狱。

a(() => {

 b(() => {

   c();

 });

});
await a();

await b();

c();

修改代码后确实简洁很多,但是如果滥用也很造成性能问题,如果ac方法是并行的,简单粗暴使用await会拉低整体执行的时间。

a(() => {
 b();
});

c(() => {
 d();
});

// 改为

await a();
b();

await c();
d();

改了之后虽然看起来是b等待a执行完,d等待c执行完,但是实际上d需要等ac都执行完才能执行,白白增加了等待的时长。
这种情况需要使用Promise.all()或者把两个执行完全隔离开来。

所以,await的使用也需要考虑具体的执行逻辑。

我们再来看一个串行并行的情况:

async function asyncAwaitFn(str) {
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(str)
        }, 1000);
    })
}

const serialFn = async () => { //串行执行

    console.time('test')
    console.log(await asyncAwaitFn('string 1'));
    console.log(await asyncAwaitFn('string 2'));
    console.timeEnd('test')
}

serialFn();
串行
async function asyncAwaitFn(str) {
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(str)
        }, 1000);
    })
}
const zhix= async () => { //并行执行
    console.time('zhix')
    const test1 = asyncAwaitFn('string 1');
    const test2 = asyncAwaitFn('string 2')

    //直接打印
    console.log(await test1)
    console.log(await test2)
    console.timeEnd('zhix')
}
zhix()
并行

相比串行,并行执行的效率快了差不多一倍。如果多个串行执行改为并行,能大大提升执行速度。

上一篇 下一篇

猜你喜欢

热点阅读