题目描述
请实现一个 AsyncScheduler 类,用于控制异步任务的并发执行数量,满足以下要求: 构造函数接收最大并发数 concurrency。 提供 add(task) 方法,接收返回 Promise 的异步任务函数,返回一个新的 Promise。 任何时候同时运行的异步任务数量不超过 concurrency。 任务按照添加顺序依次开始执行(非并行任务的顺序保证)。 当某个任务失败时,不影响其他任务的执行。 进阶要求:支持任务取消功能(选做)。
思路&js代码
1、递归
class AsyncScheduler {
constructor(concurrency) {
// 初始化代码
this.concurrency = concurrency
this.tasks = []
this.runningCount = 0
}
add(task) {
this.tasks.push(task)
this.runTask()
}
runTask() {
// 没有待执行的任务,直接返回
if (this.tasks.length === 0) return
// 超出并发数,直接返回
if (this.runningCount === this.concurrency) return
this.runningCount++
const nextTask = this.tasks.shift() // 从任务列表中取出第一个
const onEnd = () => {
this.runningCount--
this.runTask()
}
nextTask().then(onEnd).catch(onEnd)
}
// 可选:取消任务的方法
cancel(task) {
if (!task) this.tasks = []
this.tasks = this.tasks.filter(item => item !== task)
}
}
const scheduler = new AsyncScheduler(2) // 最大并发数2
const delay = (ms, val) => () =>
new Promise(resolve =>
setTimeout(() => {
console.log(val)
resolve(val)
}, ms)
)
const consoleA = delay(1000, "A")
const consoleB = delay(500, "B")
const consoleC = delay(300, "C")
const consoleD = delay(200, "D")
scheduler.add(consoleA)
scheduler.add(consoleB)
scheduler.add(consoleC)
scheduler.add(consoleD)
// scheduler.cancel(consoleC)
// 输出:B、C、A、D