我正在参与掘金会员专属活动-源码共读第一期,点击参与
前言
从事 Nodejs 开发的人对 axios 应该不会陌生,它能够构造并发起 http 请求的库。 在以前进行前端开发时,经常使用的是 JQuery 提供的 ajax 方法。它们都能够发出 http 请求。 axios 更多用在 node.js 项目中,其通过 Promise 实现 XHR 的封装。而 ajax 是通过 callback +XHR 实现。
源码分析
源码地址: github.com/axios/axios…
github 上 lib/axios.js 是主入口文件。从文件开始阅读,可以看到:其中引入了很多其他js 文件,这部分应该是一些其他工具函数,还有一个核心文件 core/axios.js 等等。
创建实例
function createInstance(defaultConfig) {
const context = new Axios(defaultConfig);
const instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});
// Copy context to instance
utils.extend(instance, context, null, {allOwnKeys: true});
// Factory for creating new instances
instance.create = function create(instanceConfig) {
return createInstance(mergeConfig(defaultConfig, instanceConfig));
};
return instance;
}
先 new 一个axios 上下文,然后将其 bind 到Axios.prototype.request 上 并返回一个新的实例。再复制 Axios.prototype 到实例上,复制 context 到 instance 实例上。再使用工厂模式创建实例,该实例可以根据用户自定义的参数创建。
其实,对上面的代码不是很理解为什么这样做?
核心 Axios 类
首先,先阅读下核心 Axios.js ,提供真正的 Axios 类:
- 其构造函数是一个带有实例配置的参数,并赋值给默认值。还有拦截器,其中分别是请求和响应的拦截器.
- request 请求方法:核心方法,分发请求。该方法通过参数获取请求地址,请求方法,然后和拦截器组成 Promise 调用链,返回 Promise 实例。其中还提供的两个 util.forEach 就是提供一些请求方法的别名,其返回的还是 Axios 的 request 方法。
- getUri 方法:获取 uri 的函数
大概了解了 Axios 类后,再说下我们使用 axios 时是怎么使用的?
// 第一种用法:
axios({
method: 'post',
url: '/user/info',
data: {
name: 'tome',
age: 18
}
}).then(result=>{}).catch((err)=>{});
// 第二种用法
axios.post('/user/info', {
name: 'tome',
age: 18
}
}).then((result)=>{}).catch((err)=>{})
第一种通过参数配置config 对象进行请求,这个时候就会调用 createInstance 方法。发起请求其实就是 request 方法,所以会先创建一个上下文环境,然后将上下文环境绑定到该请求上,并返回实例。所以我们可以直接使用第一种方法进行调用。
在核心文件 axios中,还提供了util.forEach 两个请求方法别名的请求。其中也是返回axios,prototype.request 请求的,所以可以使用第二种方法。在 createInstance 方法中会将 axios.prototype 和 上下文环境 context 绑定到实例上原因吧。
大概对创建实例的过程进行阅读解析,其还有很多源码的内容还需要继续深入的学习和分析。