思路:
1.用一个按钮点击生成基于Promise的定时器用来模拟请求
2.设置一个容器(数组),每次按钮点击后将新的请求“装入”其中,生成请求队列,并开始执行
3.始终执行容器中先进入的请求(先进先出),并在每一个请求结束重新判断循环执行的条件
以下是原生js代码
// 模拟请求函数,使用 setTimeout 模拟请求耗时
function mockRequest(id) {
return new Promise((resolve) => {
// 生成 1 - 3 秒之间的随机时间
const randomTime = Math.floor(Math.random() * 3 + 1) * 1000;
console.log(`Request ${id} 开始, 在 ${randomTime / 1000} 后完成请求`);
setTimeout(() => {
console.log(`Request ${id} 完成.`);
resolve();
}, randomTime);
});
}
// 初始化参数
const concurrency = 10;
const queue = [];
let activeCount = 0;
// 处理队列中的请求
function processQueue() {
// 当队列不为空且当前并发请求数量小于最大并发数时
while (queue.length > 0 && activeCount < concurrency) {
// 从队列头部取出一个请求
const request = queue.shift();
console.log(request);
// 增加当前正在执行的请求数量
activeCount++;
request()
.then(() => {
// 请求完成后,减少当前正在执行的请求数量
activeCount--;
// 继续处理队列中的下一个请求
processQueue();
})
.catch(() => {
// 请求出错时,同样减少当前正在执行的请求数量
activeCount--;
// 继续处理队列中的下一个请求
processQueue();
});
}
}
// 请求 ID 计数器
let requestId = 1;
// 获取按钮元素
const button = document.getElementById('requestButton');
// 为按钮添加点击事件监听器
button.addEventListener('click', () => {
// 生成一个新的请求
const newRequest = () => mockRequest(requestId++);
queue.push(newRequest)
processQueue();
});
不停的点击这个按钮,用来触发向容器中添加队列的效果