并发任务控制

90 阅读1分钟

以下是对这段代码的详细解释: 首先,定义了一个名为 timeout 的函数,它接受一个时间参数 time 。通过 setTimeout 来创建一个异步操作,并返回一个 Promise 对象。当设定的时间到达时,resolve 这个 Promise 。 然后,定义了一个 SuperTask 类。 在类的构造函数中,接受一个参数 parallelCount ,默认为 2 。并初始化了一些属性,如任务数组 task 和正在运行的任务数量 runningCountadd 方法用于添加任务。它返回一个 Promise 对象,并将任务信息(包括任务函数、resolve 函数和 reject 函数)放入 task 数组中,然后调用 _run 方法。 _run 方法用于执行任务。只要正在运行的任务数量小于最大并行数量且任务数组中有任务,就取出任务数组的第一个任务进行执行。执行任务时,先增加正在运行的任务数量,通过 Promise.resolve 执行任务函数,并处理 thenfinally 回调。在 finally 中,减少正在运行的任务数量,并再次调用 _run 方法。 最后,创建了一个 SuperTask 的实例 superTask 。 定义了 addTask 函数,它接受任务执行时间 time 和任务名称 name ,通过 superTask.add 来添加任务,并在任务完成时打印相关信息。 接着,依次调用 addTask 函数添加了 5 个任务。

function timeout(time) {
            return new Promise(resolve => {
                setTimeout(() => {
                    resolve();
                }, time)
            })
        }

        class SuperTask {
            constructor(parallelCount = 2) {
                this.parallelCount = parallelCount;
                this.task = [];
                this.runningCount = 0;
            }
            add(task) {
                return new Promise((resolve, reject) => {
                    this.task.push({
                        task,
                        resolve,
                        reject
                    });
                    this._run();
                })
            }

            _run() {
                while (this.runningCount < this.parallelCount && this.task.length) {
                    const { task, resolve, reject } = this.task.shift();
                    this.runningCount++;
                    Promise.resolve(task()).then(resolve, reject).finally(() => {
                        this.runningCount--;
                        this._run();
                    })
                }
            }
        }

        const superTask = new SuperTask();
        function addTask(time, name) {
            superTask.add(() =>
                timeout(time)
            ).then(() => {
                console.log(`任务${name}完成`)
            })
        }

        addTask(1000, 1);
        addTask(1000, 2);
        addTask(1000, 3);
        addTask(1000, 4);
        addTask(1000, 5);