[轉] Vue中異步錯誤處理


一般在一個項目開始之前,我們一般會對現有的框架做一定功能上的豐富,比如對ajax請求功能的二次封裝,封裝的功能可能包含了:通用錯誤處理,請求過濾,響應過濾等等。如果我們封裝的函數叫request,那么業務中觸發一個ajax請求的流程大致如圖:
正常ajax請求流程圖
通常,這樣的流程處理能滿足需求,然而,更多的情況,我們希望request的返回數據,經過request預處理后,首先交由業務代碼這邊自行判斷是否合法,是否需要處理錯誤,如果不合法,且自己不打算處理錯誤,則再拋出錯誤,這樣的話,就符合很多后端框架的流程了,業務層的錯誤,先自己catch,要么處理,要么往框架拋,框架統一處理,流程大致如圖:
改造后的request請求圖

這樣的話,所有的錯誤,業務層有了優先處理的權利,不需要自行處理的情況才交由框架做通用處理。
當然,在javascript中,異步錯誤的處理不能簡簡單單地通過window.onerror可以搞定的,在vue下改造,具體的思路是將我們需要按新的流程處理的函數處理成async函數,這樣,我們就能用promise的那套錯誤處理機制來處理了。
具體實現看代碼:

//為了不影響vue自有的Vue.config.errorHandler正常工作 //我們再單獨定義一個異步錯誤處理函數 Vue.config.asyncErrorHandler = err => { console.log('catch async error:', err) } 
JavaScript
//然后是在vue實例創建之前,包裹所有method方法 //根據method執行后返回的是否是promise,來決定是否需要catch錯誤 Vue.mixin({ beforeCreate() { const methods = this.$options.methods || {} Object.keys(methods).forEach(key => { let fn = methods[key] this.$options.methods[key] = function(...args) { let ret = fn.apply(this, args); if (ret && typeof ret.catch === 'function') { return ret.catch(Vue.config.asyncErrorHandler) } else { return ret } } }) }, }) 
JavaScript

這樣的話,我們在新建vue實例的時候,將我們需要按新流程處理錯誤的方法聲明為async:

new Vue({ el: '#test', methods: { async fn() { this.name = 'click' await timeout() // <==== timeout中reject的錯誤會被捕獲 }, async fn1() { this.name = 'click1' throw {msg:'async函數中同步拋錯',status:1000} // <==== 同步拋錯也會被捕獲 }, test() { // 原來的方式書寫method,人為觸發不捕獲, // 生命周期中調用被Vue.config.errorHandler捕獲 throw { msg: '非async方法還是按照原來的方式處理錯誤', status: 3000 } } } }) 
JavaScript

測試代碼:https://jsfiddle.net/a408115319/od5fgL4v/28/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM