await/async無法捕獲與處理錯(cuò)誤信息的解決方案分享
前言
如果你對(duì)同步任務(wù)/異步任務(wù)/回到地獄/promise概念/async-await的作用不是很了解的話,或許需要看一下以下簡(jiǎn)單的介紹。
如果都了解則可以直接點(diǎn)擊側(cè)邊欄跳到下面看await無法處理錯(cuò)誤信息的解決方案。
同步和異步
javascript是一個(gè)單線程的語言。因?yàn)槭菃尉€程。所以這直接導(dǎo)致了線程阻塞的問題,在前一個(gè)任務(wù)完成以前,后面所有的任務(wù)都無法執(zhí)行。因?yàn)檫@個(gè)問題。所以javascript有了異步任務(wù)的概念。
javascript把其中的任務(wù)分為兩部分,一種是同步任務(wù),一種是異步任務(wù),一些可能造成阻塞的任務(wù)歸為異步任務(wù),并將異步任務(wù)放到所有的同步任務(wù)之后去執(zhí)行,以解決阻塞問題。
常見的異步任務(wù)有
- settimeout/setInterval
- Promise的then函數(shù)
- XMLHttpRequest(http請(qǐng)求也就是ajax)
異步任務(wù)解決了執(zhí)行堵塞的問題,同時(shí)也存在一些問題(如下)。
異步任務(wù)所存在的問題
異步任務(wù)需要回調(diào)來處理任務(wù)結(jié)束以后的一些動(dòng)作。在一些特殊場(chǎng)景下,有些異步任務(wù)需要依賴于其他異步任務(wù)的回調(diào)。這就需要將需要依賴的異步任務(wù)寫到被依賴的異步任務(wù)的回調(diào)中。
這是一種解決依賴異步依賴的方案,雖然可行,但不可讀。 總會(huì)出現(xiàn)依賴層級(jí)較多的情況,大量的層級(jí)會(huì)讓這個(gè)功能變得非常晦澀。可讀性極差。如下??

雖然一般開發(fā)中很少會(huì)出現(xiàn)這種嵌套7層的異步任務(wù)。但嵌套3,4層還是相對(duì)常見的。多層的嵌套配合本身存在的邏輯。對(duì)代碼的閱讀非常不友好。前端工程師們?yōu)榱私鉀Q這個(gè)問題。在ES6中推出了Promise。
Promise如何解決回調(diào)地獄
Promise提供resolve和reject兩個(gè)函數(shù)來代表異步任務(wù)的成功和失敗。最關(guān)鍵的一點(diǎn)是Promise提供了.then()和.catch()函數(shù),.then()函數(shù)負(fù)責(zé)處理異步任務(wù)成功后的動(dòng)作,.catch()負(fù)責(zé)處理異步任務(wù)失敗后的動(dòng)作。
他們?cè)谝欢ǔ潭壬蟽?yōu)化了回調(diào)地獄

Promise還可以進(jìn)行鏈?zhǔn)秸{(diào)用

雖然Promise對(duì)于地獄回調(diào)有所改善。但他依然有著一定的嵌套結(jié)構(gòu)存在。有沒有什么方案可以徹底脫離嵌套結(jié)構(gòu)?
有
es6后來又推出了async/await(Promise的語法糖)。
async/await,回調(diào)地獄的最終方案
async/await完全解決了回調(diào)嵌套的問題。實(shí)現(xiàn)了以看似同步的代碼,完成異步的需求。
async右邊的函數(shù)會(huì)返回一個(gè)Promise對(duì)象。如圖??

await是等待一個(gè)async函數(shù)執(zhí)行完畢,并提取Promise中的值。??

這樣,我們就擺脫了嵌套結(jié)構(gòu)的問題?,F(xiàn)在我們來看下整套一起使用。

async/await錯(cuò)誤處理方案
async/await作為promise的語法糖。它徹底解決了回調(diào)地獄的問題,但也存在一個(gè)問題。相對(duì)于Promise的鏈?zhǔn)秸{(diào)用。async/await無法捕獲錯(cuò)誤。普通的Promise是通過.catch()和reject()配合來進(jìn)行錯(cuò)誤程序處理。但是async/await并沒有在語法內(nèi)部提供錯(cuò)誤處理。
這就導(dǎo)致了如果異步請(qǐng)求錯(cuò)誤,我們無法做出相應(yīng)補(bǔ)救措施而且錯(cuò)誤信息會(huì)在控制臺(tái)打印。


現(xiàn)在我們常規(guī)await的處理方案有以下幾種。
第一種,手動(dòng)添加啊try{}catch{}進(jìn)行捕獲
我們可以通過手動(dòng)給async函數(shù)內(nèi)部添加*try{}catch{}*來進(jìn)行錯(cuò)誤捕獲,如此,就可以避免錯(cuò)誤在控制臺(tái)打印和阻塞代碼的運(yùn)行。如下

這種做法的弊端是:需要捕獲錯(cuò)誤的async多的話。每一個(gè)都寫下去,就比較麻煩和不可讀了。
第二種,使用await-to-js庫
網(wǎng)上總有大牛幫我們解決這些問題。await-to-js是一個(gè)幫助我們解決異步錯(cuò)誤處理的庫,知名度較高,到目前有2.7k的?。
import to from "await-to-js";
//模擬請(qǐng)求
const handleFetch = async () => {
fetch("/url",{})
}
//進(jìn)行錯(cuò)誤捕獲和處理
const [err, result] = await to(handleFetch());
if (err) {
//進(jìn)行錯(cuò)誤動(dòng)作處理
}這是一種比較簡(jiǎn)單的處理方式
源碼 ---ts版本
| --- | ------------------------------------------------------------------------------------- |
| | * @param { Promise } promise |
| | * @param { Object= } errorExt - Additional Information you can pass to the err object |
| | * @return { Promise } |
| | */ |
| | export function to<T, U = Error> ( |
| | promise: Promise<T>, |
| | errorExt?: object |
| | ): Promise<[U, undefined] | [null, T]> { |
| | return promise |
| | .then<[null, T]>((data: T) => [null, data]) |
| | .catch<[U, undefined]>((err: U) => { |
| | if (errorExt) { |
| | const parsedError = Object.assign({}, err, errorExt); |
| | return [parsedError, undefined]; |
| | } |
| | |
| | return [err, undefined]; |
| | }); |
| | } |
| | |
| | export default tots版本的源碼可能不便于閱讀,以下是我翻譯成js版本的源碼 ,并附加注解
export function to(
promise,
errorExt,
) {
return promise
//成功,則error返回null,result返回data
.then((data) => [null, data])
//錯(cuò)誤則捕獲錯(cuò)誤內(nèi)容,然后返回錯(cuò)誤信息,result為undefined
.catch((err) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return [parsedError, undefined];
}
return [err, undefined];
});
}最后
相較于自己使用try和catch進(jìn)行捕獲,我更喜歡使用await-to-js這個(gè)庫,簡(jiǎn)單方便,而且貼近hooks的寫法讓我覺得親切。
是否有必要給每一個(gè)請(qǐng)求都加上一個(gè)錯(cuò)誤捕獲?我想是不需要的。我們需要知道,錯(cuò)誤捕獲并不是無償?shù)?。在很多情況下我們并不需要去做這種特殊的處理,比如獲取分頁數(shù)據(jù)等。一般情況,只需要給一些可能會(huì)出現(xiàn)問題的async/await做這個(gè)處理即可。
總結(jié)
捕獲async和await的方法有兩種
- 手動(dòng)添加try{}catch{}
- 使用await-to-js異步錯(cuò)誤處理庫
到此這篇關(guān)于await/async無法捕獲與處理錯(cuò)誤信息的解決方案的文章就介紹到這了,更多相關(guān)await/async無法捕獲與處理錯(cuò)誤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何解決JavaScript中的數(shù)組長(zhǎng)度不對(duì)的問題
JavaScript?中的數(shù)組長(zhǎng)度是一個(gè)比較常見的坑,理解數(shù)組長(zhǎng)度的工作原理非常重要,下面就跟隨小編一起來了解下如何解決JavaScript中的數(shù)組長(zhǎng)度不對(duì)的問題吧2024-12-12
js使用eval解析json實(shí)例與注意事項(xiàng)分享
eval函數(shù)在js中有不少用處了,下面我來給各位朋友介紹eval解析json的實(shí)例,基于這個(gè)實(shí)例我們引出來在eval處理json數(shù)據(jù)時(shí)的一些注意事項(xiàng),希望文章對(duì)各位同學(xué)會(huì)有所幫助2014-01-01
JS實(shí)現(xiàn)的系統(tǒng)調(diào)色板完整實(shí)例
這篇文章主要介紹了JS實(shí)現(xiàn)的系統(tǒng)調(diào)色板,結(jié)合完整實(shí)例形式分析了js實(shí)現(xiàn)調(diào)色板效果的具體步驟與實(shí)現(xiàn)技巧,涉及js數(shù)值計(jì)算與頁面元素操作的方法,需要的朋友可以參考下2016-12-12
layui清空,重置表單數(shù)據(jù)的實(shí)例
今天小編就為大家分享一篇layui清空,重置表單數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09

