class RequestPool {
constructor({ max, asyncFun, debug = false }) {
// 最大并发数
this.max = max;
// 请求池
this.pool = [];
// 全部的请求参数
this.urls = [];
// 请求函数
this.asyncFun = asyncFun;
// debug
this.debug = debug;
}
// 传入请求队列参数,所有请求完成后的回调函数
step(urls, onFulfilledCallback) {
this.urls = urls;
this.onFulfilledCallback = onFulfilledCallback ? onFulfilledCallback : () => {};
while (this.pool.length < this.max && this.urls.length > 0) {
const params = this.urls.shift();
this.setTask(params);
}
this.run(Promise.race(this.pool));
}
// 通过race监听请求,完成则添加新的请求,并再次监听
run(race) {
race.then(() => {
const params = this.urls.shift();
this.setTask(params);
this.run(Promise.race(this.pool));
})
}
// 添加任务到池里,任务完成删除池子里的任务
setTask(params) {
if (!params) {
return;
}
const task = this.asyncFun(params);
this.pool.push(task);
this.log('start');
task.then(() => {
const index = this.pool.indexOf(task);
this.pool.splice(index, 1);
this.log('end');
if (this.pool.length === 0) {
this.onFulfilledCallback();
}
})
}
// 日志
log(state) {
if (!this.debug) {
return;
}
if (state === 'start') {
console.log(`%c请求开始,进行中的请求数量${this.pool.length},剩余请求数量${this.urls.length}`, 'color:#E6A23C');
}
if (state === 'end') {
console.log(`%c请求完成,进行中的请求数量${this.pool.length},剩余请求数量${this.urls.length}`, 'color:#67C23A');
}
}
}
使用
const pool = new RequestPool({
max: 3,
asyncFun: asyncFun,
debug: true
})
function asyncFun(num) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num)
}, Math.random() * 1000 + 2000)
})
}
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
pool.step(nums, () => {
console.log(`%c全部请求完成`, 'color:#67C23A')
});