Axios核心原理:Promise链串联请求与拦截器
<|begin▁of▁sentence|># 1. 前言
在之前的文章中,我们介绍了`axios`的拦截器,并使用`Promise`实现了一个简单版的拦截器。在文中还提到了`axios`的核心工作原理:**`axios`的核心是`Promise`,然后使用`Promise`的特性来处理请求和响应拦截器`。`**
那么,`axios`内部究竟是如何实现整个`Promise`链的?又是如何将请求拦截器和响应拦截器以及`axios`请求串联成一个完整的`Promise`链?本篇文章将从源码角度来探索`axios`的核心工作原理。
# 2. 从使用方式入手
在探索源码之前,我们先回忆一下`axios`是如何使用的:
```javascript
// 添加请求拦截器
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response;
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error);
}
);
// 发送请求
axios({
method: "get",
url: "http://www.baidu.com",
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
```
从上面的代码中我们可以看到,当我们发送请求时,是先添加了请求拦截器,然后又添加了响应拦截器,最后再执行`axios`请求。那么,整个`Promise`链又是如何将这些串联起来的呢?
# 3. 源码探索
为了搞清楚这个问题,我们直接上源码,源码位置在`lib/core/Axios.js`中,找到`Axios.prototype.request`方法,该方法就是`axios`发送请求的入口,代码如下:
```javascript
Axios.prototype.request = function request(config) {
// 代码省略...
// 处理config,判断参数,代码省略...
// 将拦截器数组和发送请求的数组拼接成一个数组
var requestInterceptorChain = [];
var synchronousRequestInterceptors = true;
this.interceptors.request.forEach(function unshiftRequestInterceptors(
interceptor
) {
if (
typeof interceptor.runWhen === "function" &&
interceptor.runWhen(config) === false
) {
return;
}
synchronousRequestInterceptors =
synchronousRequestInterceptors && interceptor.synchronous;
requestInterceptorChain.unshift(
interceptor.fulfilled,
interceptor.rejected
);
});
var responseInterceptorChain = [];
this.interceptors.response.forEach(function pushResponseInterceptors(
interceptor
) {
responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
});
var promise;
if (!synchronousRequestInterceptors) {
var chain = [dispatchRequest, undefined];
Array.prototype.unshift.apply(chain, requestInterceptorChain);
chain = chain.concat(responseInterceptorChain);
promise = Promise.resolve(config);
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
return promise;
}
// 代码省略...
};
```
从上面代码中可以看到,`request`方法内部定义了两个数组:`requestInterceptorChain`和`responseInterceptorChain`,分别用来存放请求拦截器和响应拦截器。然后通过`forEach`方法遍历`this.interceptors.request`和`this.interceptors.response`,将每个拦截器的`fulfilled`和`rejected`方法分别`unshift`和`push`到对应的数组中。
接下来,定义了一个`promise`变量,然后判断` synchronousRequestInterceptors`是否为`true`,这个变量是用来判断请求拦截器是否是同步的,默认是`true`,如果请求拦截器中有异步的,那么就会进入`if`分支。
在`if`分支中,定义了一个`chain`数组,初始值为`[dispatchRequest, undefined]`,其中`dispatchRequest`是发送请求的方法,`undefined`是为了占位,因为`then`方法需要两个参数,一个是成功的回调,一个是失败的回调。
然后,使用`Array.prototype.unshift.apply(chain, requestInterceptorChain)`将请求拦截器数组`requestInterceptorChain`中的方法`unshift`到`chain`数组的前面。
接着,使用`chain = chain.concat(responseInterceptorChain)`将响应拦截器数组`responseInterceptorChain`中的方法`concat`到`chain`数组的后面。
此时,`chain`数组的结构如下:
```javascript
[
requestInterceptorChain[0], // 请求拦截器成功的回调
requestInterceptorChain[1], // 请求拦截器失败的回调
...,
dispatchRequest, // 发送请求的方法
undefined, // 占位
responseInterceptorChain[0], // 响应拦截器成功的回调
responseInterceptorChain[1], // 响应拦截器失败的回调
...,
]
```
然后,使用`Promise.resolve(config)`创建一个`Promise`实例,并将`config`作为参数传入。
接下来,使用`while`循环,每次从`chain`数组中取出两个元素,一个是成功的回调,一个是失败的回调,然后调用`promise.then`方法,将这两个回调传入。
最后,返回`promise`。
这样,整个`Promise`链就串联起来了。
# 4. 流程图
为了更直观的理解整个`Promise`链的串联过程,我们可以画一个流程图:

# 5. 总结
通过本文的学习,我们了解了`axios`的核心工作原理:**`axios`的核心是`Promise`,然后使用`Promise`的特性来处理请求和响应拦截器。** 并且通过源码分析,我们知道了`axios`内部是如何将请求拦截器和响应拦截器以及`axios`请求串联成一个完整的`Promise`链的。
希望本文能够帮助你更好的理解`axios`的工作原理。
最新文章
- 固态电池与ADAS技术:突破传统汽车电气架构的革命性结合
- 车况检测保障行车安全
- 智能化固态电池驱动未来汽车
- 行车安全必知:如何正确保持安全车距与制动距离
- 电动汽车电池技术突破:固态电池与800V高压平台引领未来
- 高强度铝合金汽车轻量化车身材料
- 智能网联与固态电池技术引领未来出行革命
- 掌握安全跟车距离:车速、3秒法则与刹车性能全解析
- 智能驾驶技术革新:从L3到L4的自动驾驶演进之路
- 三角警示牌使用指南:反光材质与双闪灯的安全要点
- 自动驾驶技术突破:激光雷达降本与V2X通信推动L4级落地
- 智能驾驶技术:传感器融合与车路协同的未来发展
- 激光雷达:自动驾驶汽车的3D视觉革命
- V2X与激光雷达:车联网如何重塑未来智能驾驶体验
- V2X技术革命:破解城市拥堵的智能交通新方案
- 新能源车主必看:充电桩安全使用与冬季保养全攻略
- 汽车无法启动原因排查
- 汇编语言程序设计实验:数据操作与调试技巧
- 汽车未来科技发展趋势
- 汽车防腐蚀涂层技术应用研究
