Skip to content

Instantly share code, notes, and snippets.

@mvaldesdeleon
Created January 16, 2018 15:04
Show Gist options
  • Save mvaldesdeleon/5a7728a8379c29bfe5c7a46e8bb91825 to your computer and use it in GitHub Desktop.
Save mvaldesdeleon/5a7728a8379c29bfe5c7a46e8bb91825 to your computer and use it in GitHub Desktop.
Run promises concurrently, wait until they are all settled
const runConcurrently = concurrency => factories => {
const queue = [];
const lock = () => new Promise(resolve => {
if (concurrency > 0) {
concurrency--
resolve()
} else {
queue.push(resolve)
}
})
const run = factory => () => {
const promise = factory()
return promise.catch(() => Promise.resolve()).then(() => promise)
}
const unlock = result => {
if (queue.length) {
queue.shift()()
} else {
concurrency++
}
return result
}
return factories.map(factory => lock().then(run(factory)).catch(rejected => (unlock(), Promise.reject(rejected))).then(unlock))
}
const settleAll = promises => Promise.all(promises.map(promise => promise.catch(() => null))).then(() => promises)
// Test code follows
const workload = (label, success, result, delay) => () => new Promise((resolve, reject) => {
console.log(`Workload started: ${label}`)
setTimeout(() => {
console.log(`Workload completed: ${label}`)
return success ? resolve(result) : reject(result)
}, delay)
})
let workloads = [workload('A', true, 1, 1000), workload('B', false, 2, 1000), workload('C', true, 3, 1000), workload('D', false, 4, 1000), workload('E', true, 5, 1000)];
settleAll(runConcurrently(2)(workloads)).then(() => console.log('all done!'))
// Profit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment