Skip to content

Instantly share code, notes, and snippets.

@homuler
Created November 18, 2023 07:36
Show Gist options
  • Save homuler/ad74109ff7c64e938cb3cb5c556b6900 to your computer and use it in GitHub Desktop.
Save homuler/ad74109ff7c64e938cb3cb5c556b6900 to your computer and use it in GitHub Desktop.
An implementation of throttled Promise.all in TypeScript
interface ThrottleOptions {
concurrency: number;
}
export async function throttledAll<T>(generator: Generator<Promise<T>>, options: ThrottleOptions): Promise<T[]> {
const { concurrency } = options;
if (concurrency <= 0) {
throw new Error(`concurrency must be greater than 0, but ${concurrency}`);
}
return new Promise((resolve, reject) => {
const promises: Promise<T>[] = [];
let resolved = false;
const tryNext = (): boolean => {
const { value, done } = generator.next();
if (!done) {
const promise: Promise<T> = value.then((res) => {
tryNext();
return res;
}).catch((e) => { reject(e); throw e; });
promises.push(promise);
} else if (!resolved) {
resolve(Promise.all(promises));
resolved = true;
}
return !done;
}
for (let i = 0; i < concurrency; i++) {
if (!tryNext()) {
break;
}
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment