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>) {
// Add an async task to the queue
}
}
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> = [];
Set the concurrency limit
constructor(concurrency: number) {
if(concurrency <= 0) {
throw new Error("Concurrency must be 0")
}
this.concurrency = concurrency;
}
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();
});
}
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
private runNext() {
if (this.running >= this.concurrency) return;
if (this.tasks.length === 0) return;
const next = this.tasks.shift()!;
next();
}
That's all folks!
Top comments (0)