Promise任务调度例子

395 阅读1分钟

Scheduler

js实现一个带并发限制的异步调度器,保证同时运行的任务最多有两个

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

输出顺序是 2314

一开始1,2两个任务执行

500ms后,2执行完毕,输出2,3开始执行

800ms后,3执行完毕,输出3,4开始执行

10000ms后,1执行完毕,输出1,此时只剩下4还没执行完毕

1200ms后,4执行完毕,输出4

const assert = function (condition, msg) {
    if (!condition) {
        throw new Error(msg)
    }
}
class Scheduler {
    constructor() {
        this.runQueue = []
        this.waitQueue = []
        this.maxRunTask = 2
    }
    addTask(timestamp = 0, str = '') {
        const toString = Object.prototype.toString
        assert(toString.call(timestamp) == '[object Number]', 'timestamp must be number')
        this.waitQueue.push({
            timestamp, str
        })
        this.runLoop()
    }
    runLoop() {
        while (this.runQueue.length < this.maxRunTask && this.waitQueue.length > 0) {
            const fn = () => {
                new Promise(resolve => {
                    const task = this.waitQueue.shift()
                    setTimeout(() => {
                        console.log(task.str)
                        resolve()
                    }, task.timestamp)
                }).then(() => {
                    this.runQueue = this.runQueue.filter(f => f != fn)
                    this.runLoop()
                })
            }
            fn()
            this.runQueue.push(fn)
        }
    }
}

var scheduler = new Scheduler()
function addTask(timestamp, str) {
    scheduler.addTask(timestamp, str)
}
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')