export class SchedulerPromiseWithMaxConcurrency<T> {
// 最大并发数
private readonly _maxConcurrency;
// 正在运行的任务数
private _runningCnt = 0;
// 还未运行的任务队列
private _tasks: {
promiseCreator: () => Promise<T>;
resolve: (value: T | PromiseLike<T>) => void;
reject: (reason?: any) => void;
}[] = [];
constructor(maxConcurrency: number) {
if (maxConcurrency <= 0) {
throw new Error('maxConcurrency must be greater than 0');
}
this._maxConcurrency = maxConcurrency;
}
/**
* 添加任务
*/
add(promiseCreator: () => Promise<T>) {
return new Promise<T>((resolve, reject) => {
this._tasks.push({
promiseCreator,
resolve,
reject,
});
this._run();
});
}
private _run() {
// 已经达到最大并发
if (this._runningCnt >= this._maxConcurrency) {
return;
}
// 还未运行的任务队列为空
if (this._tasks.length === 0) {
return;
}
this._runningCnt++;
const { promiseCreator, resolve, reject } = this._tasks.shift()!;
promiseCreator()
.then(resolve, reject)
.finally(() => {
this._runningCnt--;
this._run();
});
}
}
export function promiseAllSettledWithMaxConcurrency<T>(tasks: (() => Promise<T>)[], maxConcurrency: number) {
const scheduler = new SchedulerPromiseWithMaxConcurrency(maxConcurrency);
return Promise.allSettled(tasks.map(task => scheduler.add(task)));
}