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`的工作原理。
最新文章
- 智能驾驶技术突破:从L3到L4的五年变革之路
- 暴雨台风地震行车指南:发动机、悬挂与天窗防护要点
- 智能车载电子系统集成方案
- 刹车踏板与汽车安全关系
- 自动驾驶技术革新汽车未来
- 未来出行革命:电动化、智能化与自动驾驶如何重塑交通
- 宝马驾驶体验无与伦比的舒适
- 汽车清洁保养小技巧分享
- 电动汽车自动驾驶充电技术:现状与未来发展趋势
- 三角警示牌使用指南:安全驾驶必备知识与选购要点
- 结垢发动机动力性能提升燃油喷射涡轮增压轻质合金可变气门正时可变压缩比燃烧效率功率输出散热系统优化
- 电动汽车三大核心技术:电池、电机、电控发展趋势解析
- 固态电池突破:高能量密度与硫化物电解质技术解析
- 车龄与保养指南:不同阶段养护重点及费用解析
- 智能驾驶与新能源汽车:车联网技术的未来展望
- 车损险全解析:碰撞事故、自然灾害及维修发票理赔指南
- 智能驾驶技术:现状、挑战与未来发展趋势
- 激光雷达:自动驾驶的3D慧眼与安全革命
- 激光雷达技术赋能自动驾驶:从原理到未来发展趋势
- 汽车ABS与防盗系统核心技术解析及维护指南
