实现一个带并发限制的异步调度器Scheduler,最多同时运行两个任务
1.async 版
//异步调度器
class Scheduler {
constructor(maxNum) {
//等待执行的任务队列
this.taskList = []
//当前任务数
this.count = 0
//最大任务数
this.maxNum = maxNum
}
async add(promiseCreator) {
//当当前任务数超出最大任务数就将其加入等待执行的任务队列
if (this.count >= this.maxNum) {
await new Promise(resolve => {
this.taskList.push(resolve)
})
}
this.count++
const result = await promiseCreator()
this.count--
//当其它任务执行完任务队列中还有任务没执行就将其出队并执行
if (this.taskList.length > 0) {
this.taskList.shift()()
}
return result
}
}
const timeout = time => {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
const scheduler = new Scheduler(2)
const addTask = (time, value) => {
scheduler.add(() => {
return timeout(time).then(() => {
console.log(value)
})
})
}
addTask(1000, "1")
addTask(500, "2")
addTask(300, "3")
addTask(400, "4")
//此处输出2 -> 3 ->1 -> 4
//一开始一、2两个任务进入队列
//500ms时,2完成,输出2,任务3进入队列
//800ms时,3完成,输出3,任务4进入队列
//1000ms时,1完成,输出1
//1200ms时,4完成,输出4
复制代码
2. promise版
//异步调度器
class Scheduler {
constructor(maxNum) {
//等待执行的任务队列
this.taskList = []
//等待执行的任务控制队列
this.handleList = []
//当前任务数
this.count = 0
//最大任务数
this.maxNum = maxNum
}
run(promiseCreator) {
this.count++
return promiseCreator().then((res) => {
this.count--
if (this.handleList.length) this.handleList.shift()();
return res
})
}
add(promiseCreator) {
//当当前任务数超出最大任务数就将其加入等待执行的任务队列
if (this.count >= this.maxNum) {
const promise = new Promise((resolve) => this.handleList.push(resolve))
this.taskList.push(promise)
}
if (this.taskList.length) {
return this.taskList.shift().then(() => this.run(promiseCreator))
}
return this.run(promiseCreator)
}
}
const timeout = time => {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
const scheduler = new Scheduler(2)
const addTask = (time, value) => {
scheduler.add(() => {
return timeout(time).then(() => {
console.log(value)
})
})
}
addTask(1000, "1")
addTask(500, "2")
addTask(300, "3")
addTask(400, "4")
复制代码
3. promise精简版
//异步调度器
class Scheduler {
constructor(maxNum) {
//等待执行的任务队列
this.taskList = []
//当前任务数
this.count = 0
//最大任务数
this.maxNum = maxNum
}
run() {
this.count++
this.taskList.shift()().then((result) => {
this.count--
if(this.taskList.length) this.run()
})
}
add(promiseCreator) {
this.taskList.push(() => promiseCreator())
//当当前任务数小于最大任务数就将其任务执行
this.count < this.maxNum && this.run()
}
}
复制代码