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)
複製代碼