axios支持拦截请求和响应ios
//设置请求拦截器
const myInterceptor = axios.interceptors.request.use((config)=>{
return config;
}, (error) => {
return Promise.reject(error);
});
//取消请求拦截器
axios.interceptors.request.eject(myInterceptor);
axios('https://api.github.com/users/mzabriskie').then(function (res) {
//todo
}).catch(function(){
//todo
})
复制代码
response的使用和request是同样的。git
有一点须要注意是拦截器的执行顺序,request 拦截器先加入的后执行,response 拦截器则是先加入的先执行。github
axios的基本调用流程,参照文章传送门。axios(url).then().catch(),实际上是调用Axios.prototype.request方法axios
在文件axios/lib/core/Axios.js
中api
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(), //请求拦截器
response: new InterceptorManager() //响应拦截器
};
}
Axios.prototype.request = function request(config) {
//...
//设置config
var chain = [dispatchRequest, undefined];
var promise = Promise.resolve(config);
//将添加的请求拦截器加到chain中
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
//将添加的响应拦截器加到chain中
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
chain.push(interceptor.fulfilled, interceptor.rejected);
});
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
return promise;
};
复制代码
咱们来看看new InterceptorManager()
定义了怎样的对象,进入到axios/lib/core/InterceptorManager.js
文件promise
function InterceptorManager() {
this.handlers = [];
}
//添加拦截器,返回下标做为ID
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
this.handlers.push({
fulfilled: fulfilled,
rejected: rejected
});
return this.handlers.length - 1; //返回下标做为ID
};
//根据下标ID,进行移除拦截器
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);
}
});
};
复制代码
拦截器管理模块InterceptorManager,创建了一个handlers队列来管理添加的拦截器。bash
在Axios.prototype.request方法中,使用chain.unshift将this.interceptors.request添加到chain中,因此request 拦截器先加入的后执行。可是,使用chain.push将this.interceptors.response,因此response 拦截器先加入的先执行。源码分析
最终Axios.prototype.request方法返回的promise等价于下面代码,post
Promise.resolve(config)
.then(interceptors.request, interceptors.request)
...//多个请求拦截器
.then(dispatchRequest, undefined)
...//多个响应拦截器
.then(interceptors.response, interceptors.response)
复制代码