Intesting Limit Promise
一道很有趣的并发控制写法,类似async-pool
class ConcurrencyTask {
callBack = () => {}
task = () => {}
promise = null
constructor(task, callBack) {
this.task = task
this.callBack = callBack
}
beginExecuteTask() {
this.promise = new Promise((resolve, reject) => {
this.task(resolve, reject)
})
return this.promise
}
static SimulationTask(time) { // 模拟性质,自己生成执行方法,应该由用户传入执行方法
return new ConcurrencyTask(
(resolve) => {
console.log(`开始执行延时任务${time}`);
setTimeout(() => {
resolve(time)
}, time)
},
(res) => {
console.log(res);
})
}
}
class ConcurrencyQueue {
// 最大并发数
maxConcurrencyNum = 1
// 并发任务集合
concurrencyTasks = []
// 正在进行任务
executionTasks = []
constructor(maxConcurrencyNum, ...concurrencyTasks) {
this.maxConcurrencyNum = maxConcurrencyNum
this.concurrencyTasks = [...this.concurrencyTasks, ...concurrencyTasks]
}
async beginExecuteTasks() {
this.executionTasks = []
let allExecutionTasks = []
for(let i=0; i < this.concurrencyTasks.length; i++) {
const task = this.concurrencyTasks[i]
task.beginExecuteTask().then(res => {
this.executionTasks.splice(this.executionTasks.indexOf(task), 1)
if(task.callBack) {
task.callBack(res)
}
})
if(this.executionTasks.length < this.maxConcurrencyNum) {
this.executionTasks.push(task)
allExecutionTasks.push(task)
if(this.concurrencyTasks.length - 1 === i || this.executionTasks.length >= this.maxConcurrencyNum) {
await Promise.race(this.executionTasks.map(task => task.promise))
}
}
}
await Promise.all(allExecutionTasks.map(task => task.promise))
console.log('任务完成');
}
}
const currencyQueue = new ConcurrencyQueue(
3,
ConcurrencyTask.SimulationTask(1000),
ConcurrencyTask.SimulationTask(1000),
ConcurrencyTask.SimulationTask(1000),
ConcurrencyTask.SimulationTask(3000),
ConcurrencyTask.SimulationTask(5000),
ConcurrencyTask.SimulationTask(1000),
ConcurrencyTask.SimulationTask(3000),
ConcurrencyTask.SimulationTask(2000)
)
currencyQueue.beginExecuteTasks()Updated on 4/14/2023