前端面试题:实现一个带并发限制的异步调度器 Scheduler

        题目:实现一个带并发限制的异步调度器 Scheduler,保证同时运行的任务最多有N个。完善下面代码中的 Scheduler 类,使得以下程序能正确输出:

class Scheduler {
  add(promiseCreator) { ... }
  // ...
}

const timeout = (time) => new Promise(resolve => {
  setTimeout(resolve, time)
})

const scheduler = new Scheduler(n)
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order))
}

addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')

// 打印顺序是:2 3 1 4

我的分析:

1.Scheduler类的构造函数接收一个参数N,用来控制同时运行的任务;

2.add 接收一个函数参数,并返回一个promise;

3.需要使用一个队列来调度已添加但未运行的任务;

我的实现:

class Scheduler {
    constructor(conut){
        this.count = conut // 同时运行的最大任务数
        this.runCount = 0 // 运行中的任务数
        this.taskQueue = []
    }

    // 运行任务
    static async runTask(task, resolve, reject){
        await task().then(resolve, reject)

        this.runCount --
        if(this.taskQueue.length > 0){
            let item = this.taskQueue.shift()
            Scheduler.runTask.call(this, item.fun, item.resolve, item.reject)
        }
    }

    add(promiseCreator) {
        return new Promise((resolve, reject)=>{
            this.runCount ++
            if(this.runCount > this.count){
                this.taskQueue.push({fun:promiseCreator, resolve, reject})
            }else{
                Scheduler.runTask.call(this, promiseCreator, resolve, reject)
            }
        })
    }
}

运行结果:

前端面试题:实现一个带并发限制的异步调度器 Scheduler_第1张图片

其他实现: 

class Scheduler {
    constructor(max) {
        this.max = max;
        this.count = 0; // 用来记录当前正在执行的异步函数
        this.queue = new Array(); // 表示等待队列
    }
    async add(promiseCreator) {
        /*
            此时count已经满了,不能执行本次add需要阻塞在这里,将resolve放入队列中等待唤醒,
            等到count= this.max) {
            await new Promise((resolve, reject) => this.queue.push(resolve));
        }

        this.count++;
        let res = await promiseCreator();
        this.count--;
        if (this.queue.length) {
        // 依次唤醒add
        // 若队列中有值,将其resolve弹出,并执行
        // 以便阻塞的任务,可以正常执行
        this.queue.shift()();
        }
        return res;
    }
}

你可能感兴趣的:(前端,javascript)