在vue项目中,我们一般会用到axios请求库,在每个页面中,我们也一般会需要发送请求,只要是请求,就有可能会报错,一些人可能会选择在发请求的地方去捕捉错误,即使他不关心报错,也必须要捕捉错误,因为如果不捕捉,如果有错误却没有被处理的话,控制台会报错。但是在每个页面的每个请求中都去捕捉错误,是很麻烦的事,对我而已,多次写catch,在catch中填充一个空函数,我也会觉得麻烦。 还有另外一些人,可能会在axios响应拦截器中统一进行错误处理,但是对于某些页面的错误需要特殊处理的时候,这种方式又显得灵活性不够,怎么合理的处理好这两种显得有些矛盾的需求,也是困惑了我好久,终于,我找到了觉得还算优雅的方式。我的代码如下
const HandleType = {
unHandled: 0,
then: 1,
catch: 2
}
class DefaultErrorHandlerPromise{
constructor(promise, defaultErrorHandler) {
this.defaultErrorHandler = defaultErrorHandler
this.origin = promise
promise.catch((err) => {
if (this.handleType === HandleType.unHandled) {
this.defaultErrorHandler?.call(null, err)
}
})
this.handleType = HandleType.unHandled
}
then(sucessHandler, errorHandler) {
if (errorHandler != null) {
this.handleType |= HandleType.catch
}
if(sucessHandler != null) {
this.handleType |= HandleType.then
}
const promise = this.origin.then(sucessHandler, errorHandler)
return new DefaultErrorHandlerPromise(promise, this.defaultErrorHandler)
}
catch(errorHandler) {
this.handleType |= HandleType.catch
const promise = this.origin.catch(errorHandler)
return new DefaultErrorHandlerPromise(promise, this.defaultErrorHandler)
}
}
在统一请求的地方,需要这么写
export const request = (config){
return new DefaultErrorHandlerPromise(service.request(config), () => {
console.log('统一处理');
});
};
这样在页面发请求时,如果我们不关心错误,就不需要写catch语句,这样就会走统一的错误处理流程,如果你想有不同的错误处理逻辑,就可以在catch语句中写上你的错误处理逻辑。这样会不会觉得优雅了一些呢?如下面的示例
request(xxx).then().catch(err => console.log('单独进行错误处理'))
Promise.all([request(xxx)]).then().catch(err => console.log('单独进行错误处理'))