實現一個帶併發限制的異步調度器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()
}
}
複製代碼