Skip to content

Instantly share code, notes, and snippets.

@pedropedruzzi
Created March 2, 2023 17:35
Show Gist options
  • Save pedropedruzzi/64fa443aa64fcb521b4fa834ceeed902 to your computer and use it in GitHub Desktop.
Save pedropedruzzi/64fa443aa64fcb521b4fa834ceeed902 to your computer and use it in GitHub Desktop.
TypeScript Experiment: run async functions with limited concurrency
// Copyright (c) 2023 Vendah Atividades de Internet LTDA. All rights reserved.
//
// This work is licensed under the terms of the MIT license.
// Get a copy at https://opensource.org/licenses/MIT.
export async function runWithLimitedConcurrency<T>(concurrency: number, jobs: (() => Promise<T>)[]): Promise<T[]> {
const setsOfJobs = batchify(jobs, Math.ceil(jobs.length / concurrency));
const promises: Promise<T[]>[] = [];
for (const [setIndex, setOfJobs] of setsOfJobs.entries()) {
const instrumentedSetOfJobs = setOfJobs.map((job, jobIndex) => () => {
console.log('starting set', setIndex, 'job', jobIndex);
return job();
});
promises.push(runSequentially(instrumentedSetOfJobs));
}
const arrayOfResults = await Promise.all(promises);
return arrayOfResults.flat();
}
function batchify<T>(items: T[], batchSize: number): T[][] {
const batches: T[][] = [];
for (let index = 0; index < items.length; index += batchSize) {
const batch = items.slice(index, index + batchSize);
batches.push(batch);
}
return batches;
}
async function runSequentially<T>(jobs: (() => Promise<T>)[]): Promise<T[]> {
const results: T[] = [];
for (const job of jobs) {
results.push(await job());
}
return results;
}
async function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function testRunWithLimitedConcurrency() {
const jobs = Array(1333).fill(async () => { await sleep(100); return Math.random(); });
const result = await runWithLimitedConcurrency(16, jobs);
console.log(result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment