源码分析
跳转至Axios.js
文件中
// 构造函数
constructor(instanceConfig) {
this.defaults = instanceConfig
// 创建对应的拦截器
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
}
}
那么,拦截器是怎么创建的呢
- 首先,我们来看下拦截器的用法
- www.axios-http.cn/docs/interc…
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
移除拦截器,可以这样:
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
给自定义的 axios 实例添加拦截器。
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
可以看到,请求拦截器和响应拦截器都是使用axios.interceptors.xxx.use
进行挂载
我们来看下源码实现
'use strict'
import utils from './../utils.js'
class InterceptorManager {
// 用一个数组来存储拦截器函数
constructor() {
this.handlers = []
}
/**
* 添加一个新的拦截器到栈中
*
* @参数 {Function} Promise.then(fulfilled)回调函数
* @参数 {Function} Promise.reject(rejected) 回调函数
*
* @return {Number} 返回ID 用来移除拦截器时使用
*
*/
use(fulfilled, rejected, options) {
this.handlers.push({
fulfilled,
rejected,
// 是否同步
synchronous: options ? options.synchronous : false,
// 运行时机
runWhen: options ? options.runWhen : null
})
return this.handlers.length - 1
}
eject(id) {
// 如果在handlers中找到对应的id,对应的位置置为空
if (this.handlers[id]) {
this.handlers[id] = null
}
}
// 重置拦截器数组
clear() {
if (this.handlers) {
this.handlers = []
}
}
// 遍历拦截器数组,如果当前的位置为Null,则跳过,否则执行回调函数
forEach(fn) {
utils.forEach(this.handlers, function forEachHandler(h) {
if (h !== null) {
fn(h)
}
})
}
}
export default InterceptorManager