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秒就能夠執行完了。

相關文章
相關標籤/搜索