const CONCURRENCY_LIMIT = 3
function asyncTaskRunner(tasks) {
const results = new Array(tasks.length).fill(0)
const totalTasks = tasks.length
let currentTaskIndex = 0
const runner = (resolve) => {
if (!Array.isArray(tasks)) {
throw new Error("tasks must be Array");
}
let taskQueue = []
const runNext = async () => {
if (taskQueue.length === 0 && currentTaskIndex === totalTasks) {
resolve(results)
return
}
if (taskQueue.length >= CONCURRENCY_LIMIT || tasks.length === 0) {
return
}
const taskIndex = currentTaskIndex;
currentTaskIndex += 1
const task = tasks.shift()
console.log('scheduling task ', taskIndex)
taskQueue.push(task)
task()
.then(result => {
console.log('finished task: ', taskIndex)
results[taskIndex] = result
taskQueue = taskQueue.filter((t => t !== task))
runNext()
})
}
for (let i = 0 ; i < CONCURRENCY_LIMIT; i++) {
if (tasks.length === 0) {
break
}
const taskIndex = currentTaskIndex;
currentTaskIndex += 1
const task = tasks.shift()
console.log('scheduling task ', taskIndex)
taskQueue.push(task)
task()
.then(result => {
console.log('finished task: ', taskIndex)
results[taskIndex] = result
taskQueue = taskQueue.filter((t => t !== task))
runNext()
})
}
};
return new Promise((res) => runner(res));
}
const t1 = () => new Promise(res => setTimeout(() => res('t1'), 3000))
const t2 = () => new Promise(res => setTimeout(() => res('t2'), 200))
const t3 = () => new Promise(res => setTimeout(() => res('t3'), 1500))
const t4 = () => new Promise(res => setTimeout(() => res('t4'), 5000))
const t5 = () => new Promise(res => setTimeout(() => res('t5'), 4000))
const t6 = () => new Promise(res => setTimeout(() => res('t6'), 1000))
const tasks = [t1, t2, t3, t4, t5, t6]
asyncTaskRunner(tasks)
.then(console.log)
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)