Skip to content

Instantly share code, notes, and snippets.

@marsgpl
Created July 15, 2022 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marsgpl/ed02d16fbe75d89e0987b748e62c0a6e to your computer and use it in GitHub Desktop.
Save marsgpl/ed02d16fbe75d89e0987b748e62c0a6e to your computer and use it in GitHub Desktop.
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