精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從不用try-catch實現的async/await語法來說說錯誤處理

開發 前端
前不久看到 Dima Grossman 寫的 How to write async await without try-catch blocks in Javascript。看到標題的時候,我感到非常好奇。我知道雖然在異步程序中可以不使用 try-catch 配合 async/await 來處理錯誤,但是處理方式并不能與 async/await 配合得很好,所以很想知道到底有什么辦法會比 try-catch 更好用。

[[208471]]

前不久看到 Dima Grossman 寫的 How to write async await without try-catch blocks in Javascript。看到標題的時候,我感到非常好奇。我知道雖然在異步程序中可以不使用 try-catch 配合 async/await 來處理錯誤,但是處理方式并不能與 async/await 配合得很好,所以很想知道到底有什么辦法會比 try-catch 更好用。

Dima 去除 try-catch 的方法

當然套路依舊,Dima 講到了回調地獄,Promise 鏈并最終引出了 async/await。而在處理錯誤的時候,他并不喜歡 try-catch 的方式,所以寫了一個 to(promise) 來對 Promise 進行封裝,輔以解構語法,實現了同步寫法但類似 Node 錯誤標準的代碼。摘抄代碼如下

  1. // to.js 
  2. export default function to(promise) { 
  3.     return promise 
  4.         .then(data => { 
  5.             return [null, data]; 
  6.         }) 
  7.         .catch(err => [err]); 
  8.  

應用示例:

  1. import to from "./to.js"
  2.  
  3. async function asyncTask(cb) { 
  4.     let err, user, savedTask; 
  5.  
  6.     [err, user] = await to(UserModel.findById(1)); 
  7.     if (!userreturn cb("No user found"); 
  8.  
  9.     [err, savedTask] = await to(TaskModel({ userId: user.id, name"Demo Task" })); 
  10.     if (err) return cb("Error occurred while saving task"); 
  11.  
  12.     if (user.notificationsEnabled) { 
  13.         const [err] = await to(NotificationService.sendNotification(user.id, "Task Created")); 
  14.         if (err) return cb("Error while sending notification"); 
  15.     } 
  16.  
  17.     cb(null, savedTask); 
  18.  

Dima 的辦法讓人產生的了熟悉的感覺,Node 的回調中不是經常都這樣寫嗎?

  1. (err, data) => { 
  2.     if (err) { 
  3.         // deal with error 
  4.     } else { 
  5.         // deal with data 
  6.     } 
  7.  

所以這個方法真的很有意思。不過回過頭來想一想,這段代碼中每當遇到錯誤,都是將錯誤消息通過 cb() 調用推出去,同時中斷后續過程。像這種中斷式的錯誤處理,其實正適合采用 try-catch。

使用 try-catch 改寫上面的代碼

要用 try-catch 改寫上面的代碼,首先要去掉 to() 封裝。這樣,一旦發生錯誤,需要使用 Promise.prototype.catch() 進行捕捉,或者使用 try-catch 對 await promise 語句進行捕捉。捕捉到的,當然是每個業務代碼里 reject 出來的 err。

然而注意,上面的代碼中并沒有直接使用 err,而是使用了自定義的錯誤消息。所以需要對 reject 出來的 err 進一步處理成指定的錯誤消息。當然這難不到誰,比如

  1. someAsync().catch(err => Project.reject("specified message")); 

然后再最外層加上 try-catch 就好。所以改寫之后的代碼是:

  1. async function asyncTask(cb) { 
  2.     try { 
  3.         const user = await UserModel.findById(1) 
  4.             .catch(err => Promise.reject("No user found")); 
  5.  
  6.         const savedTask = await TaskModel({ userId: user.id, name"Demo Task" }) 
  7.             .catch(err => Promise.reject("Error occurred while saving task")); 
  8.  
  9.         if (user.notificationsEnabled) { 
  10.             await NotificationService.sendNotification(user.id, "Task Created"
  11.                 .catch(err => Promise.reject("Error while sending notification")); 
  12.         } 
  13.  
  14.         cb(null, savedTask); 
  15.     } catch (err) { 
  16.         cb(err); 
  17.     } 
  18.  

上面這段代碼,從代碼量上來說,并沒有比 Dima 的代碼減少了多少工作量,只是去掉了大量 if (err) {} 結構。不習慣使用 try-catch 的程序員找找不到中斷點,但習慣了 try-catch 的程序員都知道,業務過程中一旦發生錯誤(異步代碼里指 reject),代碼就會跳到 catch 塊去處理 reject 出來的值。

但是,一般業務代碼 reject 出來的信息通常都是有用的。假如上面的每個業務 reject 出來的 err 本身就是錯誤消息,那么,用 Dima 的模式,仍然需要寫

  1. if (err) return cb(err); 

而用 try-catch 的模式,就簡單多了

  1. async function asyncTask(cb) { 
  2.     try { 
  3.         const user = await UserModel.findById(1); 
  4.         const savedTask = await TaskModel({ userId: user.id, name"Demo Task" }); 
  5.  
  6.         if (user.notificationsEnabled) { 
  7.             await NotificationService.sendNotification(user.id, "Task Created"); 
  8.         } 
  9.  
  10.         cb(null, savedTask); 
  11.     } catch (err) { 
  12.         cb(err); 
  13.     } 
  14.  

為什么?因為在 Dima 的模式中,if (err) 實際上處理了兩個業務:一是捕捉會引起中斷的 err ,并將其轉換為錯誤消息,二是通過 return 中斷業務過程。所以當 err 轉換為錯誤消息這一過程不再需要的時候,這種捕捉中斷再重新引起中斷的處理主顯得多余了。

繼續改進

用函數表達式改善 try-catch 邏輯

當然還有改進的空間,比如 try {} 塊中的代碼比較長,會造成閱讀不太方便,try-catch 的邏輯有被“切斷”的感覺。這種情況下可以使用函數表達式來改善

  1. async function asyncTask(cb) { 
  2.     async function process() { 
  3.         const user = await UserModel.findById(1); 
  4.         const savedTask = await TaskModel({ userId: user.id, name"Demo Task" }); 
  5.  
  6.         if (user.notificationsEnabled) { 
  7.             await NotificationService.sendNotification(user.id, "Task Created"); 
  8.         } 
  9.         return savedTask; 
  10.     } 
  11.  
  12.     try { 
  13.         cb(null, await process()); 
  14.     } catch (err) { 
  15.         cb(err); 
  16.     } 
  17.  

如果對錯誤的處理代碼比較長,也可以寫成單獨的函數表達式。

如果過程中每一步的錯誤處理邏輯不同怎么辦

如果發生錯誤,不再轉換為錯誤消息,而是特定的錯誤處理邏輯,怎么辦?

思考一下,我們用字符串來表示錯誤消息,以后可以通過 console.log() 來處理處理。而邏輯,最適合的表示當然是函數表達式,最終可以通過調用來進行統一處理

  1. async function asyncTask(cb) { 
  2.     async function process() { 
  3.         const user = await UserModel.findById(1) 
  4.             .catch(err => Promise.reject(() => { 
  5.                 // deal with error on looking for the user 
  6.                 return "No user found"
  7.             })); 
  8.  
  9.         const savedTask = await TaskModel({ userId: user.id, name"Demo Task" }) 
  10.             .catch(err => Promise.reject(() => { 
  11.                 // making model error 
  12.                 // deal with it 
  13.                 return err === 1 
  14.                     ? "Error occurred while saving task" 
  15.                     : "Error occurred while making model"
  16.             })); 
  17.  
  18.         if (user.notificationsEnabled) { 
  19.             await NotificationService.sendNotification(user.id, "Task Created"
  20.                 .catch(err => Promise.reject(() => { 
  21.                     // just print a message 
  22.                     logger.log(err); 
  23.                     return "Error while sending notification"
  24.                 })); 
  25.         } 
  26.  
  27.         return savedTask; 
  28.     } 
  29.  
  30.     try { 
  31.         cb(null, await process()); 
  32.     } catch (func) { 
  33.         cb(func()); 
  34.     } 
  35.  

甚至還可以處理更復雜的情況

現在應該都知道 .catch(err => Promise.reject(xx)),這里的 xx 就是 try-catch 的 catch 塊捕捉到的對象,所以如果不同的業務 reject 出來不同的對象,比如有些是函數(表示錯誤處理邏輯),有些是字符串(表示錯誤消息),有些是數字(表示錯誤代碼)——其實只需要改 catch 塊就行

  1. try { 
  2.        // ...    
  3.    } catch(something) { 
  4.        switch (typeof something) { 
  5.            case "string"
  6.                // show message something 
  7.                break; 
  8.            case "function"
  9.                something(); 
  10.                break; 
  11.            case "number"
  12.                // look up something as code 
  13.                // and show correlative message 
  14.                break; 
  15.            default
  16.                // deal with unknown error 
  17.        } 
  18.    }  

小結

我沒有批判 Dima 的錯誤處理方式,這個錯誤處理方式很好,很符合 Node 錯誤處理的風格,也一定會受到很多人的喜愛。由于 Dima 的錯誤處理方式給帶靈感,同時也讓我再次審視了一直比較喜歡的 try-catch 方式。

用什么方式取決于適用場景、團隊約定和個人喜好等多種因素,在不同的情況下需要采用不同的處理方式,并不是說哪一種就一定好于另一種——合適的才是***的! 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2025-04-29 08:05:00

JavaScript錯誤處理開發

2025-06-25 08:15:00

JavaScrip異步編程代碼

2024-11-13 01:00:18

asyncawait?編程

2024-03-05 18:15:28

AsyncAwait前端

2020-09-27 07:48:40

不用try catch

2024-11-04 08:20:00

try-catch編程

2025-02-12 12:00:00

前端try-catchJavaScrip

2024-05-24 08:59:15

2009-07-21 14:30:38

Scalatry-catch

2025-05-16 10:53:43

開發異步編程JavaScrip

2024-06-25 10:37:11

2025-01-16 12:00:00

try-catchfor循環

2021-06-28 07:27:43

AwaitAsync語法

2024-05-07 07:58:47

C#程序類型

2021-06-15 05:36:45

Gulpawaitasync

2024-12-02 11:07:24

Java代碼機制

2020-10-14 12:10:22

Javatry-catch代碼

2021-04-14 07:08:14

Nodejs錯誤處理

2022-02-10 09:04:50

架構

2024-04-08 00:00:00

asyncawaiPromise
點贊
收藏

51CTO技術棧公眾號

黄色欧美视频| 国产jzjzjz丝袜老师水多| 免费看成人人体视频| 亚洲尤物视频在线| 韩国精品一区二区三区六区色诱| 久久黄色小视频| 国产图片一区| 欧美午夜精品久久久久久浪潮| 久久久久天天天天| 中文字幕一区二区人妻电影| 国产精品一区二区av日韩在线| 在线一区二区观看| 欧美一区二区三区在线播放| 中文字幕在线播放av| 羞羞答答成人影院www| 日韩精品中文字幕一区二区三区| 国产亚洲黄色片| 亚洲AV成人无码一二三区在线| 爽好久久久欧美精品| 社区色欧美激情 | 国产xxx在线观看| 日本乱码一区二区三区不卡| 久久色在线观看| 91精品久久久久久| 久久精品视频国产| 久久99久久人婷婷精品综合 | 亚洲精品成人无码| 3d动漫一区二区三区在线观看| 一区二区成人在线| 久久久综合香蕉尹人综合网| 亚洲自拍偷拍另类| 亚洲网站啪啪| 亚洲一区二区精品| 中文字幕 欧美 日韩| 一区二区电影免费观看| 国产精品盗摄一区二区三区| 国产日韩亚洲精品| 一区二区视频网站| 亚洲激情综合| 久久中文精品视频| 免费毛片视频网站| 911亚洲精品| 欧美天堂亚洲电影院在线播放| 999久久欧美人妻一区二区| 免费在线视频一级不卡| 国产麻豆欧美日韩一区| 日本伊人精品一区二区三区介绍 | 91丨porny丨在线中文 | 中文字幕资源网在线观看免费| 中文字幕一区二区三区在线不卡| 国产亚洲欧美另类一区二区三区| 中文字幕av久久爽| 性久久久久久| 午夜精品一区二区三区在线 | 亚洲男人天堂av| 日本高清不卡三区| 色婷婷综合视频| 国产黑丝在线一区二区三区| 国产精品中文在线| 无码人妻av一区二区三区波多野| 激情久久婷婷| 色综合天天综合网国产成人网| 国精产品视频一二二区| 久久91精品| 日韩av在线免费看| 在线精品视频播放| 欧美性aaa| 欧美伊人久久久久久久久影院| 国产美女网站在线观看| 激情影院在线| 亚洲精品成人少妇| 国产盗摄视频在线观看| 日本亚洲精品| 最新国产精品久久精品| 伊人久久99| 日韩在线免费电影| 国产精品日韩精品欧美在线| 日韩免费三级| av一本在线| 国产精品理论在线观看| 一区二区三区视频| 黄色网址在线免费播放| 国产精品传媒视频| 欧美日韩视频免费在线观看| 日韩精品黄色| 亚洲色图在线播放| 男人天堂网站在线| 黄色影院在线看| 亚洲国产aⅴ成人精品无吗| 精品人妻大屁股白浆无码| 国产啊啊啊视频在线观看| 亚洲一区二区精品久久av| 日本男女交配视频| 麻豆网站免费在线观看| 黄色成人av在线| 蜜臀av午夜一区二区三区| 精品成人免费一区二区在线播放| 欧美吞精做爰啪啪高潮| 伊人国产精品视频| 北条麻妃一区二区三区在线观看 | 天堂在线中文| 91伊人久久大香线蕉| 免费观看成人在线| 国产免费av高清在线| 中文字幕一区二区三区av| 992tv成人免费观看| 97超碰在线免费| 色婷婷av一区二区| 欧美婷婷精品激情| 成人短视频软件网站大全app| 日韩精品中文字幕在线一区| 亚洲av无码成人精品国产| 精品理论电影| 久久久97精品| 久久久国产高清| 日本亚洲三级在线| **亚洲第一综合导航网站| 日韩一级免费毛片| 国产日产欧美一区| 一级性生活视频| 国产丝袜精品丝袜| 91黄色免费看| 亚洲少妇中文字幕| 凹凸成人精品亚洲精品密奴| 久久99久久久久久久噜噜| 毛片视频网站在线观看| 免费成人在线观看| 国产欧美日韩伦理| 日本在线www| 精品美女久久久久久免费| 91欧美视频在线| 国偷自产视频一区二区久| www.日韩欧美| 日韩精品久久久久久久| 国产在线国偷精品免费看| 久久久99爱| 成人午夜在线影视| 日本精品视频一区二区| 久久久久亚洲av无码麻豆| 亚洲人成伊人成综合图片| 久久亚洲综合国产精品99麻豆精品福利 | 欧美肥胖老妇做爰| 免费a v网站| 国产精品久久久久久| 久久91精品国产91久久跳| 懂色av蜜臀av粉嫩av分享吧最新章节| 国产成人精品网址| 一区二区三区四区视频在线| 亚洲欧洲自拍| 精品播放一区二区| 日韩高清dvd碟片| 美腿丝袜亚洲综合| 日韩av电影免费在线| 成年女人在线看片| 日韩三级av在线播放| 免费看日本黄色片| 亚洲免费影视| 国产日韩欧美亚洲一区| 毛片网站在线看| 91精品国产色综合久久不卡电影| 中文字幕av久久爽一区| 亚洲免费影视| 欧美大香线蕉线伊人久久国产精品| heyzo高清国产精品| 日韩欧美国产电影| avove在线播放| 精品一区二区三区在线播放视频| 日韩亚洲欧美精品| 精品成人av| 国产亚洲精品高潮| 久久人人爽人人爽人人片av免费| 成人免费视频播放| 福利视频免费在线观看| 99久热在线精品视频观看| 神马国产精品影院av| 中文字幕一区二区三区四区视频| 国产日韩精品一区二区浪潮av| 欧美日韩亚洲一二三| 亚洲大片精品免费| 日韩美女视频在线观看| 免费理论片在线观看播放老| 日韩欧美亚洲范冰冰与中字| 自拍偷拍亚洲天堂| 日韩国产在线观看| 少妇免费毛片久久久久久久久| 少妇一区视频| 中文字幕日韩av| 在线观看国产精品入口男同| 国产欧美视频一区二区三区| 九九热在线免费| 久久性感美女视频| 91久久精品一区| 50度灰在线| 精品国精品国产| 台湾佬中文在线| 久久网这里都是精品| 亚洲黄色小视频在线观看| 欧美肥老太太性生活| 3d动漫啪啪精品一区二区免费 | 久久久久久久久久国产| 天天干天天做天天操| 色综合天天做天天爱| 99自拍偷拍视频| 国产一区二区久久| 黄色成人在线免费观看| 亚洲资源网你懂的| 69av在线播放| av免费在线一区二区三区| 91精品国产色综合久久不卡电影| 国产精品theporn动漫| 国产日韩一级二级三级| 手机免费av片| 99精品热视频只有精品10| 日产精品高清视频免费| 精品国产乱码一区二区三区| 77777亚洲午夜久久多人| 国产一区电影| 亚洲第一福利视频| 一道本无吗一区| 色婷婷av一区| 国产专区第一页| 亚洲成av人在线观看| 亚洲二区在线播放| 中文一区二区在线观看| 欧美一区二区三区成人精品| 国产成人av福利| 欧美一级特黄aaa| 免费人成在线不卡| 欧美女人性生活视频| 亚洲国产婷婷| av无码久久久久久不卡网站| 亚洲女同中文字幕| 亚洲视频在线二区| 欧美艳星介绍134位艳星| 久热国产精品视频一区二区三区| 91综合精品国产丝袜长腿久久| 91夜夜未满十八勿入爽爽影院| 精品久久毛片| 日韩av观看网址| 亚洲精品一区| 青青草成人在线| 日韩深夜视频| 17婷婷久久www| 日韩伦理在线一区| 97久久精品国产| 欧美男男tv网站在线播放| 欧美黑人性视频| 国产亚av手机在线观看| 韩国精品久久久999| 福利在线导航136| 午夜精品久久久99热福利| 欧美家庭影院| 性色av一区二区三区红粉影视| 丁香花在线影院| 91wwwcom在线观看| 午夜欧美激情| 国产ts一区二区| 亚洲综合在线电影| 国产精品久久久久久av下载红粉| 全球最大av网站久久| 国产日韩精品综合网站| 99久久久国产| 国产精品制服诱惑| 小嫩嫩12欧美| 先锋影音亚洲资源| 天天综合一区| wwwwww欧美| 亚洲最黄网站| 粗暴91大变态调教| 男人的天堂亚洲一区| 三级av免费看| 不卡av电影在线播放| 久久亚洲AV成人无码国产野外 | 天天爽天天爽天天爽| 亚洲少妇中出一区| 永久免费看片在线播放| 欧美最猛黑人xxxxx猛交| 国产精品欧美久久久久天天影视| 日韩免费视频线观看| 五月婷婷在线播放| 伊人久久男人天堂| 在线xxxx| 欧美中文在线观看| 日韩黄色三级| 国产伦精品一区二区三区四区视频 | 日韩福利片在线观看| 色婷婷一区二区| 97人妻精品一区二区三区视频| 日韩一级黄色片| 你懂的在线看| 欧美精品日韩www.p站| 五月天国产在线| 91久久精品美女高潮| 全球av集中精品导航福利| 色一情一区二区三区四区| 欧美日韩免费| 亚洲成人av免费看| 国产成人精品亚洲777人妖| 国产福利短视频| 中文字幕一区二区视频| 日本中文字幕免费观看| 91国模大尺度私拍在线视频| 国产成人毛毛毛片| 亚洲欧美中文日韩在线| 91cn在线观看| 国产精品h在线观看| 一区二区免费| 亚洲春色在线| 亚洲深爱激情| 97免费公开视频| 国产精品视频你懂的| 国产精品7777| 7777精品伊人久久久大香线蕉的 | 亚洲视频免费播放| 欧美日韩第一区日日骚| 四虎影视在线观看2413| 蜜臀久久99精品久久久无需会员| 综合毛片免费视频| 国产成人免费观看| 欧美激情偷拍自拍| 日本黄色三级大片| 不卡视频一二三| 高h视频免费观看| 欧美日韩亚洲综合在线 欧美亚洲特黄一级| 国模无码一区二区三区| 久久中文久久字幕| 欧美色片在线观看| 免费精品视频一区二区三区| 欧美国产先锋| 在线能看的av网站| 中文字幕乱码一区二区免费| 国产无人区码熟妇毛片多| 亚洲福利影片在线| 91在线中文| 亚洲最大福利网| 久久视频国产| 午夜激情av在线| 欧美韩国日本一区| 亚洲大尺度在线观看| 亚洲男女性事视频| 玛雅亚洲电影| 蜜桃av噜噜一区二区三区| 亚洲免费网址| 成年人网站免费看| 岛国精品视频在线播放| 亚洲av成人无码网天堂| 26uuu亚洲伊人春色| 欧美黄色影院| 五十路熟女丰满大屁股| 成人va在线观看| 日韩精品一区二区av| 亚洲成人免费在线视频| 91九色美女在线视频| 精品一区日韩成人| 国产九九精品| 亚洲区自拍偷拍| 欧美日韩亚洲国产综合| 香蕉视频国产在线观看| 国产精品视频久久久久| 欧美激情电影| 亚洲精品乱码久久久久久9色| 亚洲一区二区综合| 五月婷婷免费视频| 国产成人精品电影| 欧美顶级大胆免费视频| www.五月天色| 亚洲观看高清完整版在线观看| 亚洲人在线观看视频| 欧美在线视频一区| 亚洲人做受高潮| 中文字幕av一区二区三区| 波多野结衣电车痴汉| 一区二区三区四区视频| 91九色综合| 艳母动漫在线免费观看| 高清不卡在线观看av| 久久久精品免费看| 国产一区二区三区在线播放免费观看 | 日韩av黄色片| 国产午夜精品久久久| 亚洲四虎影院| 国产三级中文字幕| 成人小视频免费观看| 亚洲综合久久网| 丝袜亚洲另类欧美重口| 亚洲国产高清在线观看| 精品久久一二三| 国产女人18毛片水真多成人如厕| 91极品身材尤物theporn| 欧美高清在线观看| 免费欧美激情| 激情文学亚洲色图| 亚瑟在线精品视频| av中文字幕在线| 成人激情直播| 日韩一区精品字幕| 青娱乐国产在线视频| 亚洲欧美日韩一区在线| 精品一区二区三区中文字幕| 1024av视频|