我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
异步并发限制
create by db on 2023-1-16 17:00:07
Recently revised in 2023-1-16 17:00:07闲时要有吃紧的心思,忙时要有悠闲的趣味
前言
异步并发数限制问题想必大家或多或少碰到过。
比如我们有 10 个兔子需要上传,现在考虑到网络并发通道阻塞问题,现在需要限制这请求数量,上传时最多一次性处理3 个,当上传的兔子超过 3 个时,未处理的兔子只能等待;不管上一个兔子是否上传成功,只要有兔子上传完成后,立即将请求资源给其余兔子使用。
那怎么处理呢?
正文
异步并发限制
/**
* 异步并发限制 *
* @param {Array} requestList 请求列表
* @param {Number} limit 并发数量
*/
function limitRequest(requestList = [], limit = 2) {
console.log("任务开始===");
let count = 0; //正在执行队列数量
let reqIndex = 0; //执行到的任务序号
//添加任务
requestList.forEach(el => {
dealRequest(el);
});
//执行任务
function dealRequest(el) {
//如果执行到的任务序号小于请求数量,并且当前正在运行个数<并发量,继续执行
if (requestList.length > reqIndex && count < limit) {
let task = requestList[reqIndex];
count++; //执行队列数 +1
reqIndex++; //执行到的任务序号
task(reqIndex)
.then(msg => {
console.log("msg", msg);
count--;
dealRequest(task);
// 当执行队列数量为 0 时,所有请求执行完毕
if (count === 0) {
console.log("任务结束");
}
})
.catch(msg => {
count--;
dealRequest(task);
// 当执行队列数量为 0 时,所有请求执行完毕
if (count === 0) {
console.log("任务结束");
}
});
}
}
}
//模拟接口请求
function getData(src) {
return new Promise((resolve, reject) => {
// 模拟请求时间,小于5s成功,大于5s失败
let time = parseInt(Math.random() * 10);
setTimeout(() => {
if (time < 5) {
console.log(`第${src}次成功,耗时${time}秒`);
resolve(src);
} else {
console.log(`第${src}次失败,耗时${time}秒`);
reject(src);
}
}, time * 1000);
});
}
let resList = [];
for (let i = 0; i < 10; i++) {
resList.push(getData);
}
//测试使用
limitRequest(resList, 3); //一次性最多执行3个任务
总结
很久没更新了,2023,疫情结束!躺平结束!
祝大家新年快乐,大展宏兔!
参考文档、
后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址
文档协议
db 的文档库 由 db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。