async/await使用小tips

async/await是一种异步解决方案,相对于其余异步解决方案,async/await语法在使用上是比较简单的,使用起来跟同步方法没有太大差别。promise

使用async/await

function promiseFn () {
    return new Promise((resolve, reject) => {
        resolve(1);
    });
}

async function asyncFn() {
    const num = await promiseFn();
    console.log(num);  
}

asyncFn();  // 1
复制代码

await 后面的内容,若是不是返回一个Promise,则会用Promise.resolve()进行一个隐式调用,确保返回的是一个Promise。异步

function notPromiseFn () {
    return 1;
}

async function asyncFn () {
    const num = await notPromiseFn();
    console.log(num);
}
async function asyncFn2 () {
    const num = await 666;
    console.log(num);   
}

asyncFn(); // 1

asyncFn2(); // 666
复制代码

因此,其实咱们能够不用管await后面返回的类型,都是可使用async/await的。但若是不是异步函数的话,其实就没有必要这么用了,直接用同步的写法就好,毕竟async/await的目的就是用同步的模式来实现异步的操做的,同步代码也使用async/await就有点画蛇添足了。async

异常处理

异常处理是平时编写代码中必需要考虑的问题,所以,在async/await中也必需要对异常状况进行处理。函数

function errorPromiseFn(type) {
    return new Promise((resolve, reject) => {
        if (type === 'error') {
            throw new Error('Error');
        }
        resolve(404);
    });
}

async function errorFn() {
    try {
        const res = await errorPromiseFn('error');
        console.log(res);
    } catch (err) {
        console.error(err);
    }
}

errorFn('error'); // 异常会被俘获
复制代码

串行与并行

咱们知道,同步代码都是串行执行的。但有的时候,咱们并不但愿都是串行执行的。好比,在须要请求多个没有相互依赖的接口数据时,最佳解决方案是并行执行。oop

function getData1() {
    return new Promise((resolve, reject) => {
        fetch(url).then(res => resolve(res));
    });
}

function getData2(url) {
    return new Promise((resolve, reject) => {
        fetch(url).then(res => resolve(res));
    });
}

async serialGetAllData() {
    // 建立promise并等待处理结果
    const data1 = await getData1();
    // 等待前面的处理结果完成,再建立promise并处理结果
    const data2 = await getData2();
    return {data1, data2};
}

serialGetAllData();
复制代码

上面的serialGetAllData就行串行的先去请求data1再去请求data2,可是data2其实并不须要等到data1请求完成后再去执行。所以,咱们但愿他们可以同步的进行。fetch

Promise.all实现异步并行

学过Promise的应该知道,Promise.all是支持多个Promise并行请求的。那么,在async/await中,咱们就能够借助Promise.all来实现并行请求了。ui

async parallelGetAllData() {
    const [data1, data2] = await Promise.all([
        getData1(),
        getData2()
    ]);
    return {data1, data2};
}

parallelGetAllData();
复制代码

先建立Promise再使用await

除了Promise.all方法外,还有另一种方法实现并行操做:先建立Promise再使用await。url

async parallelGetAllData() {
    // 建立多个promise实例
    const promise1 = getData1();
    const promise2 = getData2();
    // 同时等待多个promise的结果,
    // 假如promise1耗时三秒,promise2耗时两秒,
    // 因为promise1和promise2同时进行请求,
    // 所以只需3秒就能够获得data1和data2了
    const data1 = await promise1;
    const data2 = await promise2;
    return {data1, data2};
}
复制代码

循环体中使用async/await

有时候,咱们须要在循环体中去进行异步操做spa

async function serialLoop() {
    let promises = [getData1, getData2];
    for (let promise of promises) {
       const data = await promise();
       console.log(data);
    }
}

serialLoop();
复制代码

很显然,上面的代码是串行执行的,若是getData1须要3秒,getData2须要2秒,那么整个过程就须要5秒才能执行完成。code

在上一节中,咱们知道了async/await能够改造为并行执行

async function parallelLoop() {
    let promises = [getData1(), getData2()];
    for (let promise of promises) {
        const data = await promise;
        console.log(data);
    }
}
parallelLoop();
复制代码

这样,就只须要3秒就能够执行完了。