async&await的錯誤處理方法

一般情況下 async/await 在錯誤處理方面,主要使用 try/catch,像這樣

const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('fetch data is me');
        }, 1000);
    });
};

(async () => {
    try {
        const data = await fetchData();
        console.log('data is ->', data);
    } catch(err) {
        console.log('err is ->', err);
    }
})();

這么看,感覺倒是沒什么問題,如果是這樣呢?有多個異步操作,需要對每個異步返回的 error 錯誤狀態(tài)進行不同的處理,以下是示例代碼

const fetchDataA = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('fetch data is A');
        }, 1000);
    });
};

const fetchDataB = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('fetch data is B');
        }, 1000);
    });
};

const fetchDataC = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('fetch data is C');
        }, 1000);
    });
};

(async () => {
    try {
        const dataA = await fetchDataA();
        console.log('dataA is ->', dataA);
    } catch(err) {
        console.log('err is ->', err);
    }

    try {
        const dataB = await fetchDataB();
        console.log('dataB is ->', dataB);
    } catch(err) {
        console.log('err is ->', err);
    }

    try {
        const dataC = await fetchDataC();
        console.log('dataC is ->', dataC);
    } catch(err) {
        console.log('err is ->', err);
    }
})();

這樣寫代碼里充斥著 try/catch,有代碼潔癖的你能忍受的了嗎?async/await 本質(zhì)就是 promise 的語法糖,既然是 promise 那么就可以使用 then 函數(shù)了

(async () => {
    const fetchData = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is me');
            }, 1000);
        });
    };

    const data = await fetchData().then(data => data ).catch(err => err);
    console.log(data);
})();

在上面寫法中,如果 fetchData 返回 resolve 正確結(jié)果時,data 是我們要的結(jié)果,如果是 reject 了,發(fā)生錯誤了,那么 data 是錯誤結(jié)果,這顯然是行不通的,再對其完善。

(async () => {
    const fetchData = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is me');
            }, 1000);
        });
    };

    const [err, data] = await fetchData().then(data => [null, data] ).catch(err => [err, null]);
    console.log('err', err);
    console.log('data', data);
    // err null
    // data fetch data is me
})();

這樣是不是好很多了呢,但是問題又來了,不能每個 await 都寫這么長,寫著也不方便也不優(yōu)雅,再優(yōu)化一下

(async () => {
    const fetchData = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is me');
            }, 1000);
        });
    };

    // 抽離成公共方法
    const awaitTo = (promise) => {
        return promise
            .then(data => [null, data])
            .catch(err => [err, null]);
    }

    const [err, data] = await awaitTo(fetchData());
    console.log('err', err);
    console.log('data', data);
    // err null
    // data fetch data is me
})();

將對 await 處理的方法抽離成公共的方法,在使用 await 調(diào)用 awaitWrap 這樣的方法是不是更優(yōu)雅了呢。如果使用 typescript 實現(xiàn)大概是這個樣子

function awaitTo<T, U = any>(promise: Promise<T>): Promise<[U | null, T | null]> {
    return promise
        .then<[null, T]>((data: T) => [null, data])
        .catch<[U, null]>(err => [err, null]);
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容