一、axios使用中产生的疑惑点
- 每次request请求都要执行
axios.create
吗? - axios[
request
,get
,post
, ...] 区别在哪里? Axios.prototype.request
方法实现了什么?interceptors
拦截是怎么实现的?
二、项目中使用
我们在项目中使用axios一般都会进行简单的封装,如下代码
// request.js
import axios from 'axios';
let config = {
baseURL: '',
responseType: 'json',
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN'
};
const service = axios.create(config);
//请求拦截
service.interceptors.request.use(config=>{
showloading(); //等等其他操作
return config;
},error => {
// do something with request error
return Promise.reject(error);
})
service.interceptors.response.use(response => {
hideloading(); //等等数据转换
return response;
},error => {
// do something with response error
return Promise.reject(error);
})
export default service;
// 然后在使用时
import service from 'request.js'
service({
url: 'url',
method: 'get',
params: { ...querys }
})
以上为一个简单的自定义配置
和get请求
的调用。
三、读源码尝试解决问题
1、每次request请求都要执行 axios.create
吗?
QA:现在想想,多个请求一起发送的时候,这个
service
方法作为axios.create
的映射是执行多次么?axios.create方法是怎么执行的呢?
这些问题,我们通过查看axios源码来进行解惑
axios.create
是什么?
axios.create
返回一个 instance
函数,这个函数是经过上下文绑定的 Axios.prototype.request
方法;
也就是说我们的请求中
每次 service({...参数})请求都是调用的 axios唯一实例
的request
方法
结论:每次发送request都是
axios唯一实例
的request
方法的调用,不存在每次调用axios.create
重新创建axios实例的情况
2. axios[request
,get
,post
, ...] 区别在哪里?
- 使用方法上,如上图所示
- 在axios内部实现上,其实都是对
Axios.prototype.request
的方法调用
可以看出,最后Axios[method]
各方法都是返回经过merge处理后的request
方法
那么作为最本质的request方法到底执行了什么呢?
Axios.prototype.request
方法实现了什么?
这其中最重要的就是请求拦截和响应拦截
interceptors
拦截是怎么实现的?
1.在axios.create
中会创建axios实例,创建实例时会在内部创建两个拦截管理器
/**
* Create a new instance of Axios
*/
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
2.在Axios.prototype.request
中,使用拦截器实例给到chain
数组
// Hook up interceptors middleware
// dispatchRequest是实际发送请求的方法
var chain = [dispatchRequest, undefined];
var promise = Promise.resolve(config);
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
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;
上边代码我们可以看出, chain
数组是请求promise链式调用的关键
屡一下步骤:
- 创建一个chain数组,数组中保存了dispatchRequest,
- 把请求拦截器的两个方法放到放到chain的头部
- 把响应拦截器的两个方法放到chain的尾部
- 依赖于chain.length每次循环取chain的两个值做为到promise.then的resolve,reject
- 最后把整个promise链返回,实现promise链式调用
最后:对于axios的其他原理还未探究过深,此次仅作为一次学习记录