
当我们通过uni.addInterceptor(method, interceptor)添加api拦截器时,会依次调用
defineSyncApi("addInterceptor", callback, protocol, undefine)(method, interceptor)
wrapperSyncApi("addInterceptor", callback, protocol, undefine)(method, interceptor)
wrapperSyncApi("addInterceptor", callback, protocol, undefine)(method, interceptor)的调用过程如下
function wrapperSyncApi(name, fn, protocol, options) {return (...args) => {//name = "addIntercept"//fn = callback//protocol = protocol//options = undefine//args = [method, intercepter]const errMsg = beforeInvokeApi(name, args, protocol, options);if (errMsg) {throw new Error(errMsg);}return fn.apply(null, args);};
}
因此,接下来会调用beforeInvokeApi("addInterceptor", [method, interceptor], protocol, options),beforeInvokeApi的代码很繁琐,但是只干了一件事,就是校验我们调用uni.addInterceptor(method, interceptor)时传入的method和interceptor参数是否合法,如果参数不合法,系统会抛出一个异常,ApiInterceptor添加失败,如果参数合法,则会调用fn.apply(null, args),也就会调用到callback,uni.addInterceptor的核心就是在callback中完成的。
const callback = (method, interceptor) => {if (isString(method) && isPlainObject(interceptor)) {mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor);} else if (isPlainObject(method)) {mergeInterceptorHook(globalInterceptors, method);}
}
当我们调用uni.addInterceptor时,如果传入了method, interceptor,则会把interceptor的信息记录在scopedInterceptors中;如果只传入了interceptor,则会把interceptor的信息记录在globalInterceptors中。
紧接着调用mergeInterceptorHook(rawInterceptors, interceptor),mergeInterceptorHook的调用流程如下图:

当我们调用uni.addInterceptor(method, interceptor)添加拦截器时,会按照调用顺序依次把要添加的interceptor的各个属性合并到uni-app内置的一个常量对象scopedInterceptors中,如果说scopedInterceptors中已经包含了要添加的interceptor的属性,那么则不会被重复添加,注: 这里指的包含是指同一个function,而不是指相同实现的不同function
uni.addInterceptor("showLoading", {invoke: function(args) {},success: function(args) {}, fail: function(err) {}, complete: function(res) {},returnValue: function(args) {}
})uni.addInterceptor("showLoading", {invoke: function(args) {},success: function(args) {}, fail: function(err) {}, complete: function(res) {},returnValue: function(args) {}
})scopedInterceptors = {"showLoading": {"invoke": [function(args) { console.log("invoke1", "invoke1") }, function(args) { console.log("invoke2", "invoke2") }],"success": [function(args) { console.log("success1", "success1") }, function(args) { console.log("success2", "success2") }],"fail": [function(err) { console.log("fail1", "fail1") }, function(err) { console.log("fail2", "fail2") }],"complete": [function(res) { console.log("complete1", "complete1") }, function(res) { console.log("complete2", "complete2") }],"returnValue": [function(args) { return args }, function(args) { return undefine }]}
}
const invoke = function(args) {}
const success = function(args) {}
const fail = function(args) {}
const complete = function(args) {}
const returnValue = function(args) {}uni.addInterceptor("showLoading", {invoke,success,fail,complete,returnValue
})uni.addInterceptor("showLoading", {invoke,success,fail,complete,returnValue
})scopedInterceptors = {"showLoading": {"invoke": [function(args) {}],"success": [function(args) {}],"fail": [function(args) {}],"complete": [function(args) {}],"returnValue": [function(args) {}]}
}

和addInterceptor的流程类似,uni.removeInterceptor的核心也是在callback中完成的:
const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => {if (isString(method)) {if (isPlainObject(interceptor)) {removeInterceptorHook(scopedInterceptors[method], interceptor);} else {delete scopedInterceptors[method];}} else if (isPlainObject(method)) {removeInterceptorHook(globalInterceptors, method);}
}, RemoveInterceptorProtocol);
紧接着调用removeInterceptorHook(rawInterceptors, interceptor),removeInterceptorHook的调用流程如下图:

const invoke = function(args) {args.title = "加载中"args.mask = truereturn true
}uni.addInterceptor("showLoading", {invoke: invoke
})uni.removeInterceptor("showLoading", {invoke: invoke
})