console.info
该系类文章旨在研究 axios 的实现 。在研究源码的基础上,去理解 axios
是如何实现 ajax
请求并更好的去使用这个库。
简介
对应文件为 lib/core/Axios.js
根据前面的相关博文,该有的方法都有了,该有的配置也都已经规定好,在 Axios
这个类中,我们只需要绑定配置然后去调用相关的方法就可以了。
代码分析
类下的属性
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
绑定初始化值,和对 request
response
的注入。
当我们需要在请求开始前对请求头以及数据内容做手脚的话,就可以调用,axios.interceptors.use
,如下所示:
var axios = new Axios({/*一些默认的请求数据,具体内容见 config 一章*/})
axios.interceptors.request.use(succssCall,failCall);
function succssCall(config){
// 修改 header data 等等
}
function failCall(config){
// ...
}
类下方法
request
发送请求
Axios.prototype.request = function request(config) {
// 允许 axios('example/url'[, config]) 方式进行调用,即参数一为请求地址
if (typeof config === 'string') {
config = utils.merge({
url: arguments[0]
}, arguments[1]);
}
// 合并请求需要的 config 由于后者覆盖前者,所以重要的放后面
config = utils.merge(defaults, this.defaults, {method: 'get'}, config);
// 支持 baseURL 写法
if (config.baseURL && !isAbsoluteURL(config.url)) {
config.url = combineURLs(config.baseURL, config.url);
}
// chain 为一个数组连,刚开始中间只放了两项:发送请求函数、undefined。
// 至于为什么要有这个 undefined 看下去就懂了。
var chain = [dispatchRequest, undefined];
// 初始化一个 promise 带上我们刚合并好的 config
var promise = Promise.resolve(config);
// 将 request 的注入添加到 chain 的头部,也就是请求发送前
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
// 将 response 的注入添加到 chain 的尾部,也就是请求发送后
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
chain.push(interceptor.fulfilled, interceptor.rejected);
});
// 然后一次从 chain 中取出两项,放到 promise 中供 promise 不断的 then 方法调用
// 这也是为什么初始化 chain 时需要一个 undefined
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
return promise;
};
- [
method
] 一些快捷操作
// 对与 'delete', 'get', 'head' 这些不需要请求体的请求,添加如
// axios.get(url, config)的方法
// 但个人感觉在加一个 params 会不会好一点
utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function (url, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url
}));
};
});
// 对与 'post', 'put', 'patch' 这些需要请求体的请求,添加如
// axios.post(url, data, config)的方法
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function (url, data, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url,
data: data
}));
};
});
总结
实例化 Axios
之后,直接调用 request
就可以发送请求了。