并发请求
1.什么是并发请求
并发请求指的是同一时间发出多个请求,当其中一个请求结束的时候,在发送另一个请求,同时保证有多个请求一直在发送中,提高文件的传输效率
2.注意事项
1. 在使用el-button 组件的时候,调用函数如果不加上‘()’ 而是直接使用函数名进行调用,会有默认的 pointEvent 参数传递,函数中接收的第一个参数就会变成默认的pointEvent 参数。
<template>
<el-button @click="concurRequest">并发请求</el-button>
</template>
<script setup>
import { demoRequest } from "@/api/demo.js";
//并发请求的封装
const concurRequest = (allRequestNumber = 10, maxnumber = 3) => {
for (let index = 0; index < Math.min(allRequestNumber, maxnumber); index++) {
demoRequest()
}
demoRequest()
.then((res) => {
})
.catch((error) => {
})
.finally(() => {
});
};
</script>
2.由于接口直接写法方法里面进行调用,会导致除 循环外的次数,还会多调用一次,与预想的次数不一致,所以在接口调用,用一个函数在进行包裹下,也为了形成闭包保存接口调用时候的参数,可以用来接口调用失败的时候进行重发
3.由于需要进行报错的时候进行重发,所以接口请求外面还需要包裹一层函数来进行重发,并记录报错次数
4.记录请求结果的时候,不能使用push直接添加,而是用 index 来进行数组的赋值,因为先发出去的请求不一定就是先完成的
5.记录请求全部完成的时候是在 finally 来进行记录请求全部完成
3.完成代码
<template>
<el-button @click="concurRequest()">并发请求</el-button>
<el-button @click="getOther()">并发不同的数据,不同的接口</el-button>
</template>
<script setup>
import { demoRequest, demoRequestTwo, demoRequestThree } from "@/api/demo.js";
import concurRequestOthers from "../untils/requestAll.js";
//并发请求的封装
const concurRequest = (allRequestNumber = 10, maxnumber = 3, errorRequest = 3) => {
let requestNumber = 0; // 接口调用了多少次
let requestResult = []; // 请求结果
let requestFinish = 0; // 代表请求完成的数量
// Math.min(allRequestNumber, maxnumber) 请求的数量,和并发的数量取最小值,避免请求数量小于并发数量引起报错
// for循环模拟并发请求
for (let index = 0; index < Math.min(allRequestNumber, maxnumber); index++) {
getRequest();
}
function getRequest() {
let oldIndeX = requestNumber;
requestNumber++;
let errorCount = 0; // 记录报错重发的次数
const request = () =>
demoRequest()
.then((res) => {
if (res.code === 200) {
//记录成功结果
requestResult[oldIndeX] = res;
requestFinish++;
if (requestFinish == allRequestNumber) {
// 当所有的接口结束之后输出最后的请求结果
resolve(requestResult);
}
//接口成功继续进行调用
if (requestNumber < allRequestNumber) {
getRequest();
}
}
})
.catch((error) => {
//接口成功继续进行调用
if (errorCount < errorRequest) {
//进行报错的重发
errorCount++;
request();
} else {
//记录失败结果
requestResult[oldIndeX] = {
msg: "请求失败",
index: oldIndeX
};
requestFinish++;
if (requestFinish == allRequestNumber) {
// 当所有的接口结束之后输出最后的请求结果
resolve(requestResult);
}
if (requestNumber < allRequestNumber) {
getRequest();
}
}
})
request();
}
};
// const demo = () => {
// let request = () =>
// demoRequest()
// .then((res) => {
// if (res.code === 200) {
// //接口成功继续进行调用
// request();
// }
// })
// .catch((error) => {
// return Promise.resolve(request());
// });
// request();
// };
// 并发请求不限制 url 不限制请求数据
const urlDate = [
{
url: demoRequest,
data: {
msg: "接口请求1"
}
},
{
url: demoRequestTwo,
data: {
msg: "接口请求2"
}
},
{
url: demoRequestThree,
data: {
msg: "接口请求3"
}
},
{
url: demoRequestTwo,
data: {
msg: "接口请求4"
}
},
{
url: demoRequestThree,
data: {
msg: "接口请求5"
}
}
];
const getOther = async () => {
concurRequestOthers(urlDate);
// console.log("result", result);
};
</script>
4. 不同地址不同数据的并发请求
/**
* 并发请求,不限制请求地址,不限制请求数据
* @param {请求地址以及请求传递的数据} urlDate
* @param {需要发送的请求的次数} allRequestNumber
* @param {最大并发数} maxnumber
* @param {报错重发的次数} errorRequest
*/
const concurRequestOthers = (urlDate, allRequestNumber = urlDate.length, maxnumber = 3, errorRequest = 3) => {
return new Promise((resolve, reject) => {
let requestNumber = 0; // 接口调用了多少次
let requestResult = []; // 请求结果
let requestFinish = 0; // 代表请求完成的数量
// Math.min(allRequestNumber, maxnumber) 请求的数量,和并发的数量取最小值,避免请求数量小于并发数量引起报错
// for循环模拟并发请求
for (let index = 0; index < Math.min(allRequestNumber, maxnumber); index++) {
getRequest();
}
function getRequest() {
let oldIndeX = requestNumber;
requestNumber++;
let errorCount = 0; // 记录报错重发的次数
const request = () =>
urlDate[oldIndeX].url(urlDate[oldIndeX].data)
.then((res) => {
if (res.code === 200) {
res.index = oldIndeX;
//记录成功结果
requestResult[oldIndeX] = res;
requestFinish++;
if (requestFinish == allRequestNumber) {
// 当所有的接口结束之后输出最后的请求结果
resolve(requestResult);
}
//接口成功继续进行调用
if (requestNumber < allRequestNumber) {
getRequest();
}
}
})
.catch((error) => {
//重发3回共4回
if (errorCount < errorRequest) {
//进行报错的重发
errorCount++;
request();
} else {
//记录失败结果
requestFinish++;
if (requestFinish == allRequestNumber) {
// 当所有的接口结束之后输出最后的请求结果
resolve(requestResult);
}
if (requestNumber < allRequestNumber) {
getRequest();
}
requestResult[oldIndeX] = {
msg: "请求失败",
index: oldIndeX
};
}
})
request();
}
});
};