JavaScript中async await更優雅的錯誤處理方式
目錄
- 背景
- 為什麼要錯誤處理
- async await 更優雅的錯誤處理
- 小結
- 總結
背景
團隊來了新的小夥伴,發現我們的團隊程式碼規範中,要給 async await 新增 try...catch。他感覺很疑惑,假如有很多個(不集中),那不是要加很多個地方?那不是很不優雅?
為什麼要錯誤處理
是一個單執行緒的語言,假如不加 try ...catch ,會導致直接報錯無法繼續執行。當然不意味著你程式碼中一定要用 try...catch 包住,使用 try...catch 意味著你知道這個位置程式碼很可能出現報錯,所以你使用了 try...catch 進行捕獲處理,並讓程式繼續執行。
我理解我們一般在執行 async ahttp://www.cppcns.com
async await 更優雅的錯誤處理
但確HXKpiCLuf實如那位同事所說,加 try...catch 並不是一個很優雅的行為。所以我 Google 了一下,發現 How to write async await without try-catch blocks in script 這篇文章中提到了一種更優雅的方法處理,並封裝成了一個庫——await-to-。這個庫只有一個 function,我們完全可以將這個函式運用到我們的業務中,如下所示:
/** * @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]) // 執行成功,返回陣列第一項為 null。第二個是結果。 .catch<[U,undefined]>((err: U) => { if (errorExt) { Object.assign(err,errorExt); } return [err,undefined]; // 執行失敗,返回陣列第一項為錯誤資訊,第二項為 undefined }); } export default to;
這裡需要有一個前置的知識點:await 是在等待一個 Promise 的返回值。
正常情況下,await 命令後面是一個 Promise 物件,返回該物件的結果。如果不是 Promise 物件,就直接返回對應的值。
所以我們只需要利用 Promise 的特性,分別在 promise.then 和 promise.catch 中返回不同的陣列,其中 fulfilled 的時候返回陣列第一項為 null,第二個是結果。rejected 的時候,返回陣列第一項為錯誤資訊,第二項為 undefined。使用的時候,判斷第一項是否為空,即可知道是否有錯誤,具體使用如下:
import to from 'await-to-jhttp://www.cppcns.coms'; // 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) http://www.cppcns.comreturn 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); }
小結
async await 中新增錯誤處理個人認為是有必要的,但方案不僅僅只有 try...catch。利用 async await 和 Promise 的特性,我們可以更加優雅的處理 async await 的錯誤。
總結
到此這篇關於JavaScript中async await更優雅的錯誤處理方式的文章就介紹到這了,更多相關async await優雅錯誤處理內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!