Created
October 8, 2023 00:29
-
-
Save wmantly/b33d7ae1396f579a995ea4e4f5f7f755 to your computer and use it in GitHub Desktop.
A JS async generator function that manages concurrent execution of promises and yields their results or errors.
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
/** | |
* A generator function that manages concurrent execution of promises and yields their results or errors. | |
* @param {Function} promiseFactory - A function that returns a promise when called. | |
* @param {number} want - The total number of promises to execute. | |
* @param {number} delay - The delay (in milliseconds) to wait when reaching the concurrency limit. | |
* @param {Array} ...args - Additional arguments to pass to the promiseFactory function. | |
* @yields {Array} - Yields an array containing either an error or the result of each promise. | |
*/ | |
async function* whenReady(promiseFunc, want, delay, ...args) { | |
let working = 0; // Number of promises currently executing. | |
let out = []; // Array to store promise results. | |
let errors = []; // Array to store promise errors. | |
let sent = 0; // Number of promises sent for execution. | |
let sentErrors = 0; // Number of error results sent. | |
while (sent < want) { | |
// Yield completed promise results. | |
while (sent < out.length) { | |
yield [null, out[sent++]]; | |
} | |
// Yield error results. | |
while (sentErrors < errors.length) { | |
yield [errors[sentErrors++], null]; | |
} | |
// Check if we've reached the concurrency limit. | |
if (working + out.length + errors.length >= want) { | |
if (working + out.length >= want) { | |
await sleep(delay); // Delay if maximum concurrency is reached. | |
continue; | |
} | |
} | |
// Start executing a new promise. | |
(async () => { | |
try { | |
working++; | |
let res = await promiseFunc(...args); | |
out.push(res); // Store the result if the promise succeeds. | |
} catch (error) { | |
errors.push(error); // Store the error if the promise fails. | |
} finally { | |
working--; | |
} | |
})(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment