Q:并发请求数量过大,会在短时间内发送大量的网络请求,并且占用大量的系统资源,可能会造成接口阻塞,浏览器卡死现象,怎么才能控制并发请求数量防止频繁渲染呢?
可以考虑使用异步请求池,来控制同一时间并发请求的数量,我们可以通过维护一个请求队列来实现:
class PromisePool {
constructor(concurrency) {
this.concurrency = concurrency;
this.running = 0;
this.queue = [];
this.results = [];
this.taskCallbacks = [];
}
onTaskDone(callback) {
this.taskCallbacks.push(callback);
return this;
}
add(...tasks) {
const taskPromises = tasks.map(task => this.run(task))
return Promise.all(taskPromises);
}
run(task) {
return new Promise((resolve, reject) => {
const warppedTask = async () => {
try {
const result = await task();
this.results.push(result);
this.taskCallbacks.forEach(cb => cb(result));
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this.next();
}
}
if (this.running < this.concurrency) {
this.running++;
warppedTask();
} else {
this.queue.push(warppedTask);
}
})
}
next() {
if (this.queue.length > 0 && this.running < this.concurrency) {
const task = this.queue.shift();
this.running++;
task();
}
}
}
let pool = new PromisePool(3);
const task = [
() => new Promise(resolve => {
setTimeout(() => {
resolve('task1');
}, 1000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task2');
}, 2000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task3');
}, 3000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task4');
}, 4000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task5');
}, 1000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task6');
}, 4000)
}),
() => new Promise(resolve => {
setTimeout(() => {
resolve('task7');
}, 1000)
}),
]
执行代码输出