Axios 是用于发送 HTTP 请求的一个 JavaScript 库。中间件事一种机制,可以在请求和响应过程中添加自定义逻辑。也可以理解成插件化的一种机制,可以在代码执行过程中穿插一部分自定义逻辑。
一、Axios中间件核心逻辑
1、声明 Axios 构造函数函数
- 定义一个对象,处理请求成功以及失败之后的操作
- 定义一个数组,存储请求拦截函数、响应拦截函数
- 定义一个对象,注册请求拦截器逻辑、响应拦截器逻辑
this.chain.unshift
的操作是把请求拦截(包括成功以及失败)都放到数组的前面。
this.chain.push
的操作是把响应拦截(包括成功以及失败)都放到数组的后面。
this.chain
实际是一个包含了所有的请求拦截、请求成功后的逻辑处理、响应拦截、响应拦截后的逻辑处理。下面是它的形象代言代码: [请求成功拦截1,请求失败拦截1,请求成功拦截2,请求失败拦截2,... 请求成功后的逻辑处理,响应成功拦截1,响应失败拦截1,响应成功拦截2,响应失败拦截2,... 响应拦截后的逻辑处理]
javascript
function Axios(){
this.dispatchChain = {
fulfilled:()=>console.log('fulfilled'),
rejected:()=>console.log('rejected'),
}
//用于存储拦截器函数
this.chain = [this.dispatchChain.fulfilled,this.dispatchChain.rejected]
this.interceptors = {
request:{
use:(fulfilled,rejected)=>{
this.chain.unshift(fulfilled,rejected)
}
},response:{
use:(fulfilled,rejected)=>{
this.chain.push(fulfilled,rejected)
}
}
}
}
2、创建一个成功状态的Promise
javascript
let promise = Promise.resolve(-1)
3、执行请求拦截器、响应拦截器
使用 promise.then
链来串行执行这些拦截器,then
的第一个参数为请求(或响应)成功拦截函数,第二个参数为请求(或者响应)失败拦截函数,
javascript
Axios.prototype.request = async function(){
while(this.chain.length){
promise = promise.then(await this.chain.shift(),await this.chain.shift())
}
}
4、创建Axios实例
javascript
const ins = new Axios()
5、注册请求拦截器、响应拦截器
这里注册两个请求拦截器、两个响应拦截器
javascript
ins.interceptors.request.use( ctx=>console.log('req1'),ctx=>console.log('err1'));
ins.interceptors.request.use(ctx=>console.log('req2'),ctx=>console.log('err2'));
ins.interceptors.response.use(ctx=>console.log('res1'),ctx=>console.log('err11'));
ins.interceptors.response.use(ctx=>console.log('res2'),ctx=>console.log('err22'));
6、发起请求
生成的实例调用request
方法
css
ins.request()
二、Axios中间件核心代码
javascript
function Axios(){
this.dispatchChain = {
fulfilled:()=>console.log('fulfilled'),
rejected:()=>console.log('rejected'),
}
//用于存储拦截器函数
this.chain = [this.dispatchChain.fulfilled,this.dispatchChain.rejected]
this.interceptors = {
request:{
use:(fulfilled,rejected)=>{
this.chain.unshift(fulfilled,rejected)
}
},response:{
use:(fulfilled,rejected)=>{
this.chain.push(fulfilled,rejected)
}
}
}
}
//这会创建一个成功状态的Promise,其最终结果为 -1
let promise = Promise.resolve(-1)
Axios.prototype.request = async function(){
while(this.chain.length){
promise = promise.then(await this.chain.shift(),await this.chain.shift())
}
}
const ins = new Axios()
ins.interceptors.request.use( ctx=>console.log('req1'),ctx=>console.log('err1'));
ins.interceptors.request.use(ctx=>console.log('req2'),ctx=>console.log('err2'));
ins.interceptors.response.use(ctx=>console.log('res1'),ctx=>console.log('err11'));
ins.interceptors.response.use(ctx=>console.log('res2'),ctx=>console.log('err22'));
ins.request()
执行结果如下所示:
三、代码执行顺序
-
创建 Axios 实例
ins
。 -
通过
ins.interceptors.request.use
注册两个请求拦截器:req1
成功处理函数和err1
失败处理函数。req2
成功处理函数和err2
失败处理函数。 注册的顺序决定了它们在请求拦截器链中的执行顺序。
-
通过
ins.interceptors.response.use
注册两个响应拦截器:res1
成功处理函数和err11
失败处理函数。res2
成功处理函数和err22
失败处理函数。 注册的顺序决定了它们在响应拦截器链中的执行顺序。
-
调用
ins.request()
方法触发请求。这将触发请求拦截器链和响应拦截器链的执行。 -
请求拦截器链的执行顺序是:
req2
成功处理函数req2
失败处理函数req1
成功处理函数req1
失败处理函数
这是因为请求拦截器的
use
方法使用unshift
方法将拦截器添加到数组的开头,因此后注册的拦截器会首先执行。 -
响应拦截器链的执行顺序是:
res1
成功处理函数res1
失败处理函数res2
成功处理函数res2
失败处理函数
这是因为响应拦截器的
use
方法使用push
方法将拦截器添加到数组的末尾,因此后注册的拦截器会最后执行。
不同的拦截器注册顺序会导致不同的执行顺序,具体顺序取决于您的需求。拦截器用于在发送请求和处理响应之前执行自定义逻辑,以便对请求和响应进行处理或记录相关信息。