DEV Community

Bidisha Das
Bidisha Das

Posted on

Concurrency Limit

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)

Enter fullscreen mode Exit fullscreen mode

Top comments (0)