设计一个任务队列,控制最大并发量
// 生成任务队列
function createTask(i: Number): () => Promise<Number> {
return () => {
return new Promise((resolve) => {
setTimeout(() => resolve(i), 1000);
});
};
}
class TasksQueue {
max: number;
taskList: Array<() => Promise<Number>>;
constructor() {
this.max = 10;
this.taskList = [];
// 使用异步,自动执行
setTimeout(() => {
this.run();
}, 1000);
}
add(task: () => Promise<Number>) {
this.taskList.push(task);
}
run() {
const length = this.taskList.length;
if (!length) return;
const min = Math.min(length, this.max);
for (let i = 0; i < min; i++) {
// task 是这种形式 (i)=>Promise.resolve(i)
const task = this.taskList.shift();
// 重要 就是为了占位 tag1
this.max--;
if (task) {
task()
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
// 重要 tag1
this.max++;
this.run();
});
}
}
}
}
let taskQueue = new TasksQueue();
// 0-39 个函数
for (let i = 0; i < 40; i++) {
const task = createTask(i);
taskQueue.add(task);
}
note:tag1 是非常重要的,他代表了一个执行函数,如果没有,由于 for 循环是同步执行,当其中一个 for 0 循环完毕,他会立即执行 run 方法,按照图中所示,当第一次for 循环结束后,会有 10个在执行,第二次执行完,如果 有两个 Promise 走完,会同时有 20个 在执行,会大于 taskList的长度,来自 B站 time:2022.5.16 22:09