JavaScript中async await更優(yōu)雅的錯誤處理方式
背景
團隊來了新的小伙伴,發(fā)現(xiàn)我們的團隊代碼規(guī)范中,要給 async await 添加 try...catch。他感覺很疑惑,假如有很多個(不集中),那不是要加很多個地方?那不是很不優(yōu)雅?
為什么要錯誤處理
JavaScript 是一個單線程的語言,假如不加 try ...catch ,會導致直接報錯無法繼續(xù)執(zhí)行。當然不意味著你代碼中一定要用 try...catch 包住,使用 try...catch 意味著你知道這個位置代碼很可能出現(xiàn)報錯,所以你使用了 try...catch 進行捕獲處理,并讓程序繼續(xù)執(zhí)行。
我理解我們一般在執(zhí)行 async await 的時候,一般運行在異步的場景下,這種場景一般不應該阻塞流程的進行,所以推薦使用了 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è)務中,如下所示:
/**
* @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。第二個是結果。
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
Object.assign(err, errorExt);
}
return [err, undefined]; // 執(zhí)行失敗,返回數(shù)組第一項為錯誤信息,第二項為 undefined
});
}
export default to;
這里需要有一個前置的知識點:await 是在等待一個 Promise 的返回值。
正常情況下,await 命令后面是一個 Promise 對象,返回該對象的結果。如果不是 Promise 對象,就直接返回對應的值。
所以我們只需要利用 Promise 的特性,分別在 promise.then 和 promise.catch 中返回不同的數(shù)組,其中 fulfilled 的時候返回數(shù)組第一項為 null,第二個是結果。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);
}
小結
async await 中添加錯誤處理個人認為是有必要的,但方案不僅僅只有 try...catch。利用 async await 和 Promise 的特性,我們可以更加優(yōu)雅的處理 async await 的錯誤。
總結
到此這篇關于JavaScript中async await更優(yōu)雅的錯誤處理方式的文章就介紹到這了,更多相關async await優(yōu)雅錯誤處理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
javascript面向對象三大特征之多態(tài)實例詳解
這篇文章主要介紹了javascript面向對象三大特征之多態(tài),結合實例形式詳細分析了javascript面向對象程序設計中多態(tài)的概念、原理,并結合實例形式總結了多態(tài)的實現(xiàn)方法與使用技巧,需要的朋友可以參考下2019-07-07
解決ie11 SCRIPT5011:不能執(zhí)行已釋放Script的代碼問題
這篇文章主要介紹了ie11 SCRIPT5011:不能執(zhí)行已釋放Script的代碼 ,需要的朋友可以參考下2019-05-05
javascript HTML5文件上傳FileReader API
這篇文章主要介紹了javascript HTML5文件上傳FileReader API的相關資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-04-04
淺談javascript中執(zhí)行環(huán)境(作用域)與作用域鏈
本文主要介紹了javascript中執(zhí)行環(huán)境(作用域)與作用域鏈,并在文章結尾處做出了總結,感興趣的朋友可以看下2016-12-12
JavaScript實戰(zhàn)(原生range和自定義特效)簡單實例
下面小編就為大家?guī)硪黄狫avaScript實戰(zhàn)(原生range和自定義特效)簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08

