手写题 - 实现一个带并发限制的异步调度器

发布时间:2023年12月21日

题目

实现一个带并发限制的异步调度器 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

核心思路:考察 Promise知识点;当任务数超过规定任务数,创建微任务进行等待。

完善代码如下:

class Scheduler {
    constructor(max) {
        this.max = max;
        this.count = 0; // 当前执行中的异步操作
        this.queue = new Array(); // 记录当前的执行数组
    }
    
    async add(promiseCreator) {
        // count >= max 时,此时先不直接执行,将当前异步操作存储起来,当count满足时,再去执行
        // Promise.then的链式调用 new Promise((resolve) => { setTimeout(() => {}, 10000}).then xxxx
        if (this.count >= this.max) {
           /** 这个new Promise单纯只是为了创建个微任务去等,前面加了await,没有resolve()是不会往下走的 */
            await new Promise((resolve, reject) => {
                this.queue.push(resolve);
            });
        }
        
        /** queue某一项resolve()后会从这儿往下走  */
        this.count++;
        let res = await promiseCreator();// 执行timeout(time)
        this.count--; // 执行完1轮才往下走到这儿
        
        if (this.queue.length) {
            this.queue.shift()();//删除queue数组第一项并执行resolve()
        }
        
        return res;
    }
}
    
const timeout = (time) => new Promise(resolve => {
  setTimeout(resolve, time)
})

const scheduler = new Scheduler(n) // 任务2=>n即为2
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order))
}

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

运行结果如下:

在这里插入图片描述

文章来源:https://blog.csdn.net/Xxxxxl17/article/details/135126808
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。