在项目中我们会遇到一次请求多个接口,当所有请求结束后进行操作,也会遇到多个请求(大量)同时进行请求资源,本文就并发问题通过axios
对这两种现象进行优化处理,主要通过 axios 中 all、spread、请求拦截以及响应拦截进行处理。
axios 中 all、spread
axios
的all
和spread
都是axios
的静态方法,可以直接通过axios
对象调用。
const foo = () => {
return axios.get("https://dog.ceo/api/breeds/image/random ")
}
const bar = () => {
return axios.get("https://dog.ceo/api/breeds/list/all")
};
axios.all([foo(), bar()]).then(
axios.spread( (acct, perms) =>{
console.log(acct,'acct');
console.log(perms,'perms');
})
);
复制代码
定义的foo
和bar
必须要把axios
的请求return
,这样得到的才是一个Promise
对象。结果如下:
axios 请求拦截、响应拦截
声明三个变量:请求队列、最大并发请求数、当前并发请求数
const requestQueue = []; // 请求队列
const maxConcurrent = 3; // 最大并发请求数
let concurrentRequests = 0; // 当前并发请求数
复制代码
在请求拦截中,如果当前并发请求数没超过最大并发请求数,当前并发请求数就加 1,否则就将请求添加到请求队列中,其中config
是当前请求的配置,resolve
是解析函数。
//请求拦截设置
import axios from "axios";
axios.interceptors.request.use(
(config) => {
console.log(config,'concurrentRequests')
if (concurrentRequests < maxConcurrent) {
console.log('000000')
// 如果并发请求数量小于最大并发数,直接发送请求
concurrentRequests++;
return config;
} else {
// 如果并发请求数量达到最大并发数,将请求添加到队列中
return new Promise((resolve) => {
console.log('333333')
requestQueue.push({
config,
resolve,
});
});
}
},
(error) => {
return Promise.reject(error);
}
);
复制代码
打印结果如下:
在响应拦截中,并发请求数量减 1,如果请求队列的长度大于 0,说明有等待的请求,通过shift
取出队列中的最早的请求,同时在请求队列中删除该请求。然后当前并发请求数加 1,通过resolve(config)
触发解析函数发送请求。当调用解析函数时,相当于将 Promise 的状态从待定(pending)转变为已解析(resolved),并将传递的参数作为解析值。失败的话并发请求数量减 1,抛出异常。
//响应拦截
axios.interceptors.response.use(
(response) => {
concurrentRequests--; // 并发请求数量减2
if (requestQueue.length > 0) {
// 如果请求队列中有等待的请求,发送下一个请求
const { config, resolve } = requestQueue.shift();
concurrentRequests++;
resolve(config);
}
return response.data;
},
(error) => {
concurrentRequests--; // 并发请求数量减一
return Promise.reject(error);
}
);
复制代码
这里模仿了 10 个请求进行测试,具体如下:
// 发送请求
for (let i = 0; i < 10; i++) {
axios
.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
// 处理响应
console.log(response.data);
})
.catch((error) => {
// 处理错误
console.error(error);
});
}
复制代码
评论