Axios 源码分析(2)之拦截器
上一篇我们主要分析了请求这块的流程,想了解的点击此处了解
这一篇讲主要来分析下axios是如何实现拦截器的,这里只分析请求拦截器,
老规矩先来看下api如何使用的1
2
3
4
5
6
7axios.interceptors.request.use(function(config){
// ...
return config;
}, function(err){
// ...
return Promise.reject(err)
})
根据第一篇我们分析的,1
2
3
4
5
6
7
8
9
10
11
12function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context);
// Copy context to instance
utils.extend(instance, context);
return instance;
}
axios.interceptors
应该是在Axios.prototype
或者context
中
所以在axios/lib/core/Axios.js
中,我们看见1
2
3
4
5
6
7function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
可以看出request跟response都是new了一个InterceptorManager,都是InterceptorManager的实例,接着往下,我们看看axios/lib/core/InterceptorManager.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function InterceptorManager() {
this.handlers = [];
}
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
this.handlers.push({
fulfilled: fulfilled,
rejected: rejected
});
return this.handlers.length - 1;
};
InterceptorManager.prototype.eject = function eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null;
}
};
InterceptorManager.prototype.forEach = function forEach(fn) {
utils.forEach(this.handlers, function forEachHandler(h) {
if (h !== null) {
fn(h);
}
});
};
相当简短的代码,逻辑很清楚了,use,只不过将fulfilled, rejected
2个方法保存在this.handlers中,便于后面调用,那什么时候调用呢?
答案肯定是请求前后啦,因为拦截器request跟response本来就是为了拦截请求之前,跟请求之后,所以我们看看第一篇中,请求的时候干了什么
1 | Axios.prototype.request = function request(config) { |
我们仔细看看这段拦截器,这里的forEach
在InterceptorManager
重新被定义了,通过这里的2个forEach,我们最后拿到的chain是1
2
3[request.fulfilled, request.rejected,
dispatchRequest, undefined,
response.fulfilled, response.rejected]
这样的一个形式,然后循环赋给promise.then()
,所以最后拿到的promise就是这样1
2
3
4Promise.resolve(config)
.then(request.fulfilled, request.rejected)
.then(dispatchRequest, undefined)
.then(response.fulfilled, response.rejected)
这样就很清晰了,再发送请求dispatchRequest
之前,先执行了request.fulfilled或者 request.rejected,请求之后立刻又执行了response.fulfilled, response.rejected
好了,这就是拦截器的分析,
大概总结一下,就是通过InterceptorManager这个类的use方法去搜集拦截的回调,在request的时候去执行他们