axios发送请求前和请求结束后都会有一个拦截器的操作,这样可以便于我们对请求前的数据进行重新组装后发送请求和对于请求后获取到数据后在我们对数据操作前进行统一的操作,判断接口响应状态码做出对应的操作之后可以直接返回数据也或者对数据进行二次包装后返回
我们这里声明一个构造函数用于对每个请求和响应拦截器的函数进行保存和整合
// 拦截器管理构造函数 function InterceptorManager(){ // 当前构造函数实例化的时候需要往实例上添加一个空数组,以便于进行管理各个请求的拦截器 this.handlers=[]; }
在axios构造函数中的的拦截器对象中分别对请求拦截和响应拦截进行实例化拦截器管理构造函数,以便于对请求的拦截器进行管理
function Axios(config) { this.config = config; // axios拦截器 this.interceptors = { //进行实例化请求拦截器管理构造函数 request: new InterceptorManager(), // 进行实例化响应拦截器管理构造函数 response: new InterceptorManager() } }
在拦截器管理函数上还有一个方法,我们定义到他的原型上,以此节省实例化后使用此函数开辟的内存空间、
我们在原型上声明一个use函数,这个函数接收两个为函数的参数,只要是调用了use方法就会把这两个函数合并为一个对象,放到实例化对象后的handlers数组中,以便于管理和后期进行操作
InterceptorManager.prototype = { use(fulfilled, rejectted) { this.handlers.push({ fulfilled, rejectted }) } }
我们再次对于axios的请求进行改造把拦截器添加进去
Axios.prototype = { request(config = {}) { let promise = Promise.resolve(config); //如果没有chains的第二个参数,那么拦截器就不能正常跳转,拦截器位置就不对了 let chains = [dispatchRequest, undefined] // 请求拦截器 我们将请求拦截器的回调放到chains前面 this.interceptors.request.handlers.forEach(item => { chains.unshift(item.fulfilled, item.reject) }) // 响应拦截器 们将响应拦截器的回调放到chains后面 this.interceptors.response.handlers.forEach(item => { chains.push(item.fulfilled, item.reject) }) while (chains.length) { // 通过chains的length属性进行判断chains数组是否拥有数据,有数据则从chains数组中取出回调,从前面往后进行,每次循环都返回一个新的promise,如果成功话执行第一个,否则执行第二个 promise = promise.then(chains.unshift(), chains.unshift()) } // 把promise返回出去 return promise } }
坚持努力,无惧未来!