Created
July 15, 2022 21:10
-
-
Save marsgpl/ed02d16fbe75d89e0987b748e62c0a6e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface PromiseAllContext<T> { | |
results: T[] | |
jobs: (() => Promise<T>)[] | |
launched: number | |
} | |
async function worker<T>(context: PromiseAllContext<T>) { | |
const { jobs, results } = context | |
while (context.launched < jobs.length) { | |
const jobIndex = context.launched | |
if (jobIndex >= jobs.length) { | |
return | |
} | |
const job = jobs[jobIndex] | |
context.launched++ | |
const result = await job() | |
results[jobIndex] = result | |
} | |
} | |
function promiseAll<T>( | |
jobs: (() => Promise<T>)[], | |
concurrency: number = Infinity, | |
): Promise<T[]> { | |
if (concurrency === Infinity) { | |
return Promise.all(jobs.map(job => job())) | |
} | |
const context: PromiseAllContext<T> = { | |
results: [], | |
jobs, | |
launched: 0, | |
} | |
const workers = Array.from(Array(concurrency), | |
() => worker(context)) | |
return Promise.all(workers) | |
.then(() => context.results) | |
} | |
const JOBS_COUNT = 10 | |
const CONCURRENCY = 4 | |
const jobs = Array.from(Array(JOBS_COUNT), (_, i) => () => { | |
return new Promise(resolve => { | |
console.log('+ job', i, Math.floor(Date.now() / 1000)) | |
setTimeout(() => resolve(i * 10), 1000) | |
}) | |
}) | |
promiseAll(jobs, CONCURRENCY).then((results) => { | |
console.log('done') | |
console.log('🔸 results:', results) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment