众所周知,浏览器会限制同一域名下的并发请求数量,最大并发数一般是6~8个,因此前端针对并发数量做控制,避免请求数量过大
完整代码如下
// 前端控制请求并发数
const asyncQueue = (maxCount) => {
// 异步任务队列
const queue = []
// 正在进行的异步任务数量
let activeCount = 0
// 执行下一个异步任务
const next = () => {
// 活跃任务数量-1
activeCount--
// 队列不为空,执行下一个任务
if(queue.length > 0) {
queue.shift()()
}
}
// 执行异步任务
const run = async (fn, resolve, ...args) => {
// 活跃任务数量+1
activeCount++
// 执行异步任务
const result = fn(...args)
// 改变promise状态
resolve(result)
try {
// 等待任务执行完成
await result
} catch {}
// 进行下一个异步任务
next()
}
// 添加任务到队列
const addQueue = (fn, resolve, ...args) => {
// 入队
queue.push(run.bind(null, fn, resolve, ...args))
// 没有达到并发上线时,立即执行
if (activeCount < maxCount && queue.length > 0) {
queue.shift()()
}
}
const generator = (fn, ...args) => {
return new Promise((resolve) => {
addQueue(fn, resolve, ...args)
})
}
return generator
}
测试代码
const queue = asyncQueue(2);
function asyncFun(value, delay) {
return new Promise((resolve) => {
console.log('start ' + value);
setTimeout(() => resolve(value), delay);
});
}
const arr = [
queue(() => asyncFun('aaa', 2000)),
queue(() => asyncFun('bbb', 3000)),
queue(() => asyncFun('ccc', 2000)),
queue(() => asyncFun('ddd', 2000)),
queue(() => asyncFun('eee', 2000))
];
const result = await Promise.all(arr);
console.log(result);