DEV Community

Bukunmi Odugbesan
Bukunmi Odugbesan

Posted on

Coding Challenge Practice - Question 82

The task is to implement the AsyncTaskQueue that manages the execution of asynchronus tasks with a maximum concurrency limit.

The boilerplate code

class AsyncTaskQueue {
    constructor(concurrency: number) {
        // Initialize the queue with the specified concurrency limit
    }
    queue(task: () => Promise<void>) {


Enter fullscreen mode Exit fullscreen mode
     // Add an async task to the queue
    }
}
Enter fullscreen mode Exit fullscreen mode

The queue manages two things: A list of waiting tasks and a counter of concurrently running tasks. The class keeps three pieces of data: concurrency limit, running counter and task queue

 private concurrency: number;
 private running = 0;
 private tasks: Array<() => void> = [];
Enter fullscreen mode Exit fullscreen mode

Set the concurrency limit

constructor(concurrency: number) {
        if(concurrency <= 0) {
            throw new Error("Concurrency must be 0")
        }
        this.concurrency = concurrency;
    }
Enter fullscreen mode Exit fullscreen mode

When a task is added, the task is wrapped in a function that starts the task and tracks its completion.

queue(task: () => Promise<void>): Promise<void> {
    return new Promise((resolve, reject) => {
      this.tasks.push(() => {
        this.running++;

        task()
          .then(resolve)
          .catch(reject) // rejection is returned to caller
          .finally(() => {
            this.running--;
            this.runNext();
          });
      });

      this.runNext();
    });
  }

Enter fullscreen mode Exit fullscreen mode

If a task is completed, start the next task and increase the running counter

 private runNext() {
    if (this.running >= this.concurrency) return;
    if (this.tasks.length === 0) return;

    const next = this.tasks.shift()!;
    next();
  }
``
The process continues until all tasks are completed. 

The final code

Enter fullscreen mode Exit fullscreen mode

private runNext() {
if (this.running >= this.concurrency) return;
if (this.tasks.length === 0) return;

const next = this.tasks.shift()!;
next();
Enter fullscreen mode Exit fullscreen mode

}



That's all folks!
Enter fullscreen mode Exit fullscreen mode

Top comments (0)