JavaScript中async await更優(yōu)雅的錯誤處理方式
背景
團(tuán)隊來了新的小伙伴,發(fā)現(xiàn)我們的團(tuán)隊代碼規(guī)范中,要給 async await 添加 try...catch。他感覺很疑惑,假如有很多個(不集中),那不是要加很多個地方?那不是很不優(yōu)雅?
為什么要錯誤處理
JavaScript 是一個單線程的語言,假如不加 try ...catch ,會導(dǎo)致直接報錯無法繼續(xù)執(zhí)行。當(dāng)然不意味著你代碼中一定要用 try...catch 包住,使用 try...catch 意味著你知道這個位置代碼很可能出現(xiàn)報錯,所以你使用了 try...catch 進(jìn)行捕獲處理,并讓程序繼續(xù)執(zhí)行。
我理解我們一般在執(zhí)行 async await 的時候,一般運行在異步的場景下,這種場景一般不應(yīng)該阻塞流程的進(jìn)行,所以推薦使用了 try...catch 的處理。
async await 更優(yōu)雅的錯誤處理
但確實如那位同事所說,加 try...catch 并不是一個很優(yōu)雅的行為。所以我 Google 了一下,發(fā)現(xiàn) How to write async await without try-catch blocks in Javascript 這篇文章中提到了一種更優(yōu)雅的方法處理,并封裝成了一個庫——await-to-js。這個庫只有一個 function,我們完全可以將這個函數(shù)運用到我們的業(yè)務(wù)中,如下所示:
/** * @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]) // 執(zhí)行成功,返回數(shù)組第一項為 null。第二個是結(jié)果。 .catch<[U, undefined]>((err: U) => { if (errorExt) { Object.assign(err, errorExt); } return [err, undefined]; // 執(zhí)行失敗,返回數(shù)組第一項為錯誤信息,第二項為 undefined }); } export default to;
這里需要有一個前置的知識點:await 是在等待一個 Promise 的返回值。
正常情況下,await 命令后面是一個 Promise 對象,返回該對象的結(jié)果。如果不是 Promise 對象,就直接返回對應(yīng)的值。
所以我們只需要利用 Promise 的特性,分別在 promise.then 和 promise.catch 中返回不同的數(shù)組,其中 fulfilled 的時候返回數(shù)組第一項為 null,第二個是結(jié)果。rejected 的時候,返回數(shù)組第一項為錯誤信息,第二項為 undefined。使用的時候,判斷第一項是否為空,即可知道是否有錯誤,具體使用如下:
import to from 'await-to-js'; // If you use CommonJS (i.e NodeJS environment), it should be: // const to = require('await-to-js').default; async function asyncTaskWithCb(cb) { let err, user, savedTask, notification; [ err, user ] = await to(UserModel.findById(1)); if(!user) return cb('No user found'); [ err, savedTask ] = await to(TaskModel({userId: user.id, name: 'Demo Task'})); if(err) return cb('Error occurred while saving task'); if(user.notificationsEnabled) { [ err ] = await to(NotificationService.sendNotification(user.id, 'Task Created')); if(err) return cb('Error while sending notification'); } if(savedTask.assignedUser.id !== user.id) { [ err, notification ] = await to(NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you')); if(err) return cb('Error while sending notification'); } cb(null, savedTask); }
小結(jié)
async await 中添加錯誤處理個人認(rèn)為是有必要的,但方案不僅僅只有 try...catch。利用 async await 和 Promise 的特性,我們可以更加優(yōu)雅的處理 async await 的錯誤。
總結(jié)
到此這篇關(guān)于JavaScript中async await更優(yōu)雅的錯誤處理方式的文章就介紹到這了,更多相關(guān)async await優(yōu)雅錯誤處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中檢測數(shù)據(jù)類型的四種方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了四個JavaScript中檢測數(shù)據(jù)類型的常用方法,文中的示例代碼講解詳細(xì),具有一定的參考價值,需要的可以參考一下2023-04-04element-ui組件輸入框之放大鏡搜索圖標(biāo)問題
這篇文章主要介紹了element-ui組件輸入框之放大鏡(搜索圖標(biāo))的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-11-11javascript parseInt() 函數(shù)的進(jìn)制轉(zhuǎn)換注意細(xì)節(jié)
parseInt(string, radix) 有2個參數(shù),第一個string 是傳入的數(shù)值,第二個radix是 傳入數(shù)值的進(jìn)制,參數(shù)radix 可以忽略,默認(rèn)為 10,各種進(jìn)制的數(shù)轉(zhuǎn)換為 十進(jìn)制整數(shù),接下來詳細(xì)介紹,感興趣的朋友可以了解下哦2013-01-01js下將阿拉伯?dāng)?shù)字每三位一逗號分隔(如:15000000轉(zhuǎn)化為15,000,000)
這篇文章主要介紹了js下將阿拉伯?dāng)?shù)字每三位一逗號分隔(如:15000000轉(zhuǎn)化為15,000,000),需要的朋友可以參考下2014-06-06js location.replace與location.reload的區(qū)別
js location.replace與location.reload的區(qū)別,經(jīng)常能用的到,需要的朋友可以可以下。2010-09-09