class SuperTask {
constructor(parallelCount = 2) {
this.parallelCount = parallelCount // 并发任务数量,默认2个
this.tasks = []
this.runningCount = 0 // 正在执行的任务数量
}
/**
* 添加任务
* @param task
* @returns {Promise<unknown>}
*/
add(task) {
return new Promise((resolve,reject) => {
this.tasks.push({
task,
resolve,
reject
})
this.run() // 添加任务后,尝试执行任务
})
}
/**
* 执行任务
*/
run() {
// 当执行的任务数量小于并发任务数量 且 任务队列中有任务时执行
while (this.runningCount < this.parallelCount && this.tasks.length > 0) {
const {task,resolve,reject} = this.tasks.shift() // 从任务队列中取出第一个任务
this.runningCount++ // 正在运行的任务数量要加一
// 开始执行任务
task().then(resolve,reject).finally(() => {
this.runningCount-- // 执行完毕,在运行的任务数量要减一
this.run() // 然后再次尝试执行新的任务
})
// 展开可以写成这样
// task()
// .then(() => resolve())
// .catch((err) => reject(err))
// .finally(() => {
// this.runningCount--
// this.run()
// })
}
}
}
使用示例
// 创建一个异步任务
function timeout(time) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},time)
})
}
// 创建实例
const superTask = new SuperTask(2)
// 添加任务
function addTask(time,name) {
superTask
.add(() => timeout(time))
.then(() => {
console.log(`任务${name}完成`)
})
}
addTask(10000,1) // 10秒后输出:任务1完成
addTask(5000,2) // 5秒后输出:任务2完成
addTask(3000,3) // 8秒后输出:任务3完成
addTask(4000,4) // 12秒后输出:任务4完成
addTask(5000,5) // 15秒后输出:任务5完成