06 有并行限制的Promise调度器

300 阅读1分钟

需求

  • 任务可以是同步任务也可以是异步任务
  • 同时执行的任务上限有限制

实现

class Scheduler {

    // 限制的最大数量
    private maxCount = Infinity;
    // 正在运行的任务数量
    private runningCount = 0;
    // 任务队列
    private taskQueue: Array<() => Promise<any>> = [];

    constructor(count: number) {
        this.maxCount = count;
    }

    // 添加任务
    addTask(task: () => any) {
        const wrappedTask: () => Promise<true> = () =>
            new Promise((resolve) => {
                const res = task();
                if (res?.then) {
                    res.then(resolve);
                } else {
                    resolve(res);
                }
            });
        this.taskQueue.push(wrappedTask);
    }

    // 开始任务
    startTask() {
        const count = Math.min(
            this.maxCount - this.runningCount,
            this.taskQueue.length
        );
        for (let i = 0; i < count; i++) {
            this.request();
        }
    }

    // 任务执行
    request() {
        const task = this.taskQueue.shift();
        if (task) {
            this.runningCount++;
            task().then(() => {
                this.runningCount--;
                this.startTask();
            });
        }
    }
}