axios封装及其核心功能
项目中用到了axios
,需要对其进行简单封装,统一数据处理和错误信息等。发现发送请求的时候可以直接实例调用,不是必须显示调用request
。下面2种都可以:
const instance = axios.create({
timeout: 5000
})
return instance({
...config,
})
//或者
return instance.request({
...config,
})
很好奇:实例在不显示调用request
的情况下是怎么触发request
的呢?直接浏览源码找答案吧。
1. 实例化函数之createInstance
:初始化和创建实例的重要方法。
function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context);
// Copy context to instance
utils.extend(instance, context);
return instance;
}
//bind.js:是个闭包
module.exports = function bind(fn, thisArg) {
return function wrap() {
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
return fn.apply(thisArg, args);
};
};
重点:var instance = bind(Axios.prototype.request, context)
。
bind
的返回的是个闭包函数wrap
,使不同axios
实例之间可以隔离作用域。
所有的请求[axios, axios.get, axios.post等...]
内部调用的都是Axios.prototype.request
。完美解决了开篇的疑惑。
2. 核心方法之request
:返回promise
request
方法返回promise
(L54),可能是链式调用的promise
,这才是axios
请求真正的返回值!
那么axios
可以发送哪些请求呢?看L39,一层层找:可以发送浏览器和Node
请求。
function getDefaultAdapter() {
var adapter;
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = require('./adapters/xhr');
} else if (typeof process !== 'undefined') {
// For node use HTTP adapter
adapter = require('./adapters/http');
}
return adapter;
}
3. 超级特性之拦截器
封装的时候经常会定义一些自己的request/response
拦截器,axios
是如何处理的呢?request
方法里写的明明白白,回到L39:
先定义一个拦截器中间件chain
,推入dispatchRequest
和undefined
2个值。request
(L43)拦截器推入头部,response
(L47)拦截器推入尾部,然后通过while
循环实现链式调用。
下图看起来会更加直观和清晰:
总之:request
拦截器先加入后执行,response
拦截器先加入先执行。
参考连接
axios 核心源码实现原理
Axios 源码解析(我总觉得我解析得最全了)
看了下官网介绍axios
的几大特性,排在前三的是:
- 支持浏览器端和服务端请求
- 支持
promise
- 支持
request
和response
拦截器
发表评论 (审核通过后显示评论):