1、开发了一个工具模块:
01 // utils.js
02 export default {
03 foo(fn) {
04 fn && fn()
05 }
06 }
该模块导出一个对象,其中foo属性是一个函数,接收一个回调函数作为参数,调用foo函数时会执行该回调函数,在用户侧使用时:
01 import utils from 'utils.js'
02 utils.foo(() => {
03 // ...
04 })
2、若用户提供的回调函数在执行时出错,有两种办法可以应对,第一个办法是让用户自行处理,这需要用户自己执行try…catch:
01 import utils from 'utils.js'
02 utils.foo(() => {
03 try {
04 // ...
05 } catch (e) {
06 // ...
07 }
08 })
该方法缺点:增加用户负担
第二个方法是我们代替用户统一处理错误,代码:
01 // utils.js
02 export default {
03 foo(fn) {
04 try {
05 fn && fn()
06 } catch(e) {/* ... */}
07 },
08 bar(fn) {
09 try {
10 fn && fn()
11 } catch(e) {/* ... */}
12 },
13 }
也即在每个函数内都增加try…catch代码块,实际上,还可以进一步将错误处理程序封装为一个函数
3、继续封装,将错误处理程序封装为函数callWithErrorHandling:
01 // utils.js
02 export default {
03 foo(fn) {
04 callWithErrorHandling(fn)
05 },
06 bar(fn) {
07 callWithErrorHandling(fn)
08 },
09 }
10 function callWithErrorHandling(fn) {
11 try {
12 fn && fn()
13 } catch (e) {
14 console.log(e)
15 }
16 }
代码变得简洁了,但简洁不是目的,这样做真正的好处是能为用户提供统一的错误处理接口。
4、提供统一的错误处理接口:
01 // utils.js
02 let handleError = null
03 export default {
04 foo(fn) {
05 callWithErrorHandling(fn)
06 },
07 // 用户可以调用该函数注册统一的错误处理函数
08 registerErrorHandler(fn) {
09 handleError = fn
10 }
11 }
12 function callWithErrorHandling(fn) {
13 try {
14 fn && fn()
15 } catch (e) {
16 // 将捕获到的错误传递给用户的错误处理程序
17 handleError(e)
18 }
19 }
我们提供了registerErrirHandle函数,用户可以使用它注册错误处理程序,然后在callWithErrorHandling函数内部捕获错误后,把错误传递给用户注册的错误处理程序。
这样用户侧代码就会非常简洁且健壮:
01 import utils from 'utils.js'
02 // 注册错误处理程序
03 utils.registerErrorHandler((e) => {
04 console.log(e)
05 })
06 utils.foo(() => {/*...*/})
07 utils.bar(() => {/*...*/})
这时错误处理的能力完全由用户控制,用户既可以选择忽略错误,也可以调用上报程序将错误上报给监控系统。
以上就是Vue.js错误处理的原理,可以在源码中搜索到callWithErrorHandling函数。在vue.js中,也可以注册统一的错误处理函数:
import APP from 'App.vue'
const app = createApp(App)
app.config.errorHandler = () => {
//错误处理程序
}
摘自**《Vue.js设计与实现》 霍春阳**
仅供学习交流使用
这个封装的过程就是提高代码简洁性和健壮性的过程吗?酷