Created
January 16, 2018 15:04
-
-
Save mvaldesdeleon/5a7728a8379c29bfe5c7a46e8bb91825 to your computer and use it in GitHub Desktop.
Run promises concurrently, wait until they are all settled
This file contains 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
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