Skip to content

Instantly share code, notes, and snippets.

@wmantly
Created October 8, 2023 00:29
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 wmantly/b33d7ae1396f579a995ea4e4f5f7f755 to your computer and use it in GitHub Desktop.
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.
/**
* 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