type Task<T> = () => Promise<T>;
type TaskWithPriority<T> = { task: Task<T>; priority: number; resolve: (value: T) => void; reject: (error: any) => void };
class AsyncQueue<T = any> {
private queue: TaskWithPriority<T>[] = [];
private running = 0;
private concurrency: number;
constructor(concurrency: number = 3) {
this.concurrency = concurrency;
}
async add(task: Task<T>, priority: number = 0): Promise<T> {
return new Promise<T>((resolve, reject) => {
this.queue.push({ task, priority, resolve, reject });
this.queue.sort((a, b) => b.priority - a.priority);
this.process();
});
}
private async process(): Promise<void> {
if (this.running >= this.concurrency || this.queue.length === 0) {
return;
}
this.running++;
const { task, resolve, reject } = this.queue.shift()!;
try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this.process();
}
}
get size(): number {
return this.queue.length;
}
get active(): number {
return this.running;
}
}
export default AsyncQueue;