Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active May 13, 2022 03:34
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 intrnl/692d5401b0a45e27602f2a4ca0972b55 to your computer and use it in GitHub Desktop.
Save intrnl/692d5401b0a45e27602f2a4ca0972b55 to your computer and use it in GitHub Desktop.
Race promises into settled values with concurrency limit
async function* raceAllSettled (iterable, concurrency = 4) {
const executing = new Set();
const consume = async () => {
const value = await Promise.race(executing);
executing.delete(value.promise);
delete value.promise;
return value;
};
for (const item of iterable) {
const promise = promised(item).then(
(value) => ({ status: 'fulfilled', value, promise }),
(reason) => ({ status: 'rejected', reason, promise }),
);
executing.add(promise);
if (executing.size >= concurrency) {
yield await consume();
}
}
while (executing.size) {
yield await consume();
}
}
const promised = (value) => {
return (value && value.then) ? value : Promise.resolve(value);
}
const promises = [
new Promise((resolve) => setTimeout(resolve, 1000, 456)),
123,
Promise.resolve(234),
Promise.reject(345),
];
for await (const value of raceAllSettled(promises)) {
console.log(value);
}
// > { status: 'fulfilled', value: 123 }
// > { status: 'fulfilled', value: 234 }
// > { status: 'rejected', value: 345 }
// > { status: 'fulfilled', value: 456 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment