type Task<T> = () => Promise<T>;
type ProgressCallback = (completed: number, total: number) => void;
class PromisePool<T = any> {
private concurrency: number;
private tasks: Task<T>[];
private results: T[] = [];
private errors: Error[] = [];
constructor(concurrency: number = 3) {
this.concurrency = concurrency;
this.tasks = [];
}
add(task: Task<T>): this {
this.tasks.push(task);
return this;
}
async execute(onProgress?: ProgressCallback): Promise<{ results: T[]; errors: Error[] }> {
this.results = [];
this.errors = [];
const executing: Promise<void>[] = [];
let completed = 0;
for (const task of this.tasks) {
const promise = task()
.then(result => {
this.results.push(result);
completed++;
onProgress?.(completed, this.tasks.length);
})
.catch(error => {
this.errors.push(error instanceof Error ? error : new Error(String(error)));
completed++;
onProgress?.(completed, this.tasks.length);
})
.finally(() => {
executing.splice(executing.indexOf(promise), 1);
});
executing.push(promise);
if (executing.length >= this.concurrency) {
await Promise.race(executing);
}
}
await Promise.all(executing);
return { results: this.results, errors: this.errors };
}
}
export default PromisePool;