Created
November 22, 2017 15:24
-
-
Save smnh/21a7fb3eb6945736ade21f3faaf075e2 to your computer and use it in GitHub Desktop.
Promise all with pool of concurrent promises
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
/** | |
* Like Promise.all(), this method resolves if all promises returned by invoking the "callback" are resolved, or rejects | |
* if at least one of these promises is rejected. This method ensures that only "poolSize" number of promises are | |
* executed at the same time. The "total" parameter specifies the number of total promises that need to be executed, | |
* therefore, the "callback" will be invoked "total" number of times. The "callback" is invoked with a single "index" | |
* parameter specifying the index of the invocation. | |
* | |
* @example | |
* let items = [...] | |
* return promiseAllPool(10, items.length, (index) => { | |
* // Return promise | |
* return processItem(items[index]); | |
* }); | |
* | |
* @param {Number} poolSize number of concurrent promises | |
* @param {Number} total number of total promises, the callback will be invoked 'total' number of times | |
* @param {Function} callback function that must return a promise, it is executed with a single 'index' parameter | |
* @return {Promise} | |
*/ | |
function promiseAllPool(poolSize, total, callback) { | |
return new Promise((resolve, reject) => { | |
let index = 0; | |
let finished = 0; | |
let results = []; | |
let hadError = false; | |
let error = null; | |
function onReject(_error) { | |
if (!hadError) { | |
hadError = true; | |
error = _error; | |
} | |
} | |
function doWork() { | |
if (index < total) { | |
let _index = index++; | |
return callback(_index).catch(onReject).then(result => { | |
results[_index] = result; | |
return doWork(); | |
}); | |
} else { | |
finished++; | |
if (finished === poolSize) { | |
if (hadError) { | |
reject(error); | |
} else { | |
resolve(results); | |
} | |
} | |
return null; | |
} | |
} | |
for (let i = 0; i < poolSize; i++) { | |
doWork(); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment