上一篇中分析了axios发送一个简单的get请求的完整的流程,传送门,戳这里。javascript
这一篇讲主要来分析下axios是如何实现拦截器的,这里只分析请求拦截器。java
axios.interceptors.request.use(function(config){
// ...
return config;
}, function(err){
// ...
return Promise.reject(err)
})
复制代码
上面的代码就是定义一个请求的拦截器,须要注意的是拦截器是要在发送请求以前定义的!ios
axios是一个函数咱们都知道了,interceptors属性是何时定义上的呢?上一篇分析了axios上好多属性都是从context和instance上继承来的,因此仍是按照整个思路分析,来看axios/lib/core/Axios.js
文件。axios
function Axios(){
this.interceptors = {
request = new InterceptorManager()
}
}
复制代码
context是Axios的实例化对象,有interceptors对象,因此axios继承来,也是能够访问的到的,清楚这一点就顺势去axios/lib/core/InterceptorManager.js
文件中看InterceptorManager这个构造函数吧!数组
function InterceptorManager(){
this.handlers = [];
}
InterceptorManager.prototype.use = function use(fulfilled, rejected){
this.handlers.push({
fulfilled : fulfilled,
rejected : rejected
});
return this.handler.length - 1;
}
复制代码
从上面能够看到,use是定义在构造函数的原型上的,因此它的实例化对象是能够访问的,因此到如今,axios.interceptors.request.use()咱们已经解释清楚了,就是上面的函数,进入函数看下到底作了什么,咱们定义的完成和失败的两个回调函数被push到一个handlers数组中去了,那么这个handlers数组到底有什么意义呢?promise
目前来讲好像分析被中断了,不知道该如和进行下去,可是上一节咱们在分析Axios.prototype.request方法的时候省略过一些关于拦截器的东西,去看看axios/lib/core/Axios.js
。函数
Axios.prototype.request = function(config){
// ...
// 对config进行处理的代码仍是省略掉
var chain = [dispatchRequest, undefind];
var promise = Promise.resolve(config);
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor){
// 这是上一节分析省略掉的一个函数
// 关于这个forEach函数就是去遍历 刚才不知道是什么用的handlers数组;
chain.unshift(interceptor.fulfilled, interceptor.rejected);
// 就是把咱们定义的拦截器的回调函数加入到chain的首部
})
// 关于response的也省略掉
// 假设咱们只定义了一组拦截器回调函数,那么如今chain应该是这样的
// chain = [fulfilled, rejected, dispatchRequest, undefined];
while(chain.length){
promise = promise.then(chain.shift(), chain.shift())
}
// 通过循环这个promise就成了
/** * promise = promise.resolve(conifg) * .then(interceptor.fulfilled, interceptor.rejected) * .then(dispatchRequest, undefined) */
return promise
}
复制代码
结合上一篇咱们知道这个函数返回的promise是咱们发送请求以后的promise,可是在发送请求以前先执行了fufilled(config)和rejected(err)组成的promise,这个promise执行而且resolve后才会去执行dispatchRequest(config);若是返回了reject那么请求promise将终止,会被axios.get().catch()捕获,因此这就是所谓的拦截。post
对响应拦截器的处理也一样是这个道理,只是将interceptor.fulfilled和interceptor.rejected回调放在了chain数组的后面,再此就不作分析啦!ui
总结一下,这个其实流程挺简单的,就是把拦截器的回调,放到发送请求的promise以前,先执行。this
关于取消请求的分析,传送门,戳这里。