interface PromiseHandlerOptions { concurrency?: number; } class PromiseHandler { private queue: Array<() => Promise> = []; private running = 0; private concurrency: number; constructor(options: PromiseHandlerOptions = {}) { this.concurrency = options.concurrency || 5; } clear = () => { this.queue = []; this.running = 0; }; add = async (task: () => Promise, ref: unknown): Promise => { if (!ref) { return Promise.resolve(); } return new Promise((resolve, reject) => { this.queue.push(async () => { try { const result = await task(); resolve(result); } catch (error: unknown) { if (error instanceof Error) { reject(error); } else { reject(new Error('Unknown error')); } } finally { if (this.running > -1) { this.running--; this.processQueue(); } } }); this.processQueue(); }); }; private processQueue = () => { // console.log('processQueue', this.running, this.queue.length); while (this.running < this.concurrency && this.queue.length > 0) { const task = this.queue.shift(); if (task) { this.running++; task(); } } }; } export const createPromiseHandler = (options?: PromiseHandlerOptions) => { return new PromiseHandler(options); }; export const promiseHandler = createPromiseHandler();