Skip to content

Instantly share code, notes, and snippets.

@mon-compte-github
Created November 13, 2021 19:36
Show Gist options
  • Save mon-compte-github/320af43774c905ed729172181803ce9f to your computer and use it in GitHub Desktop.
Save mon-compte-github/320af43774c905ed729172181803ce9f to your computer and use it in GitHub Desktop.
Promise.any polyfill :-)
if(!Promise.any) {
// may require a polyfill for AggregateError
// https://github.com/es-shims/AggregateError
Promise.prototype.any = /*async <T>*/(iterable /* Iterable<T>*/) /*: Promise<T>*/ => {
// To handle basic types we have to promisify them using Promise.resolve(promise).
return new Promise((resolve, reject) => {
const errors = [];
let first = true;
[...iterable].forEach(el => {
Promise.resolve(el).then((data) => {
// It returns a single promise that resolves as soon as any
// of the promises in the iterable fulfills, with the value
// of the fulfilled promise
if(first) {
first = false;
resolve(data);
}
}).catch((error) => {
errors.push(error);
// if all of the given promises are rejected,
// then the returned promise is rejected with an AggregateError
if(errors.length == arr.length) {
reject(new AggregateError(errors));
}
});
});
});
}
}
const err = [];
for(let k=0; k<5; k++) {
err.push( Promise.reject(k) );
}
// should throw an AggregateError
Promise.any(err).then((d) => console.log(d)).catch((error) => console.error(error));
const arr = [];
for(let k=0; k<5; k++) {
// add some random delay to each promise to make thing more realistic
arr.push( Promise.resolve(k).then((k) => new Promise(resolve => setTimeout(() => resolve(k), Math.random()*5000))) );
}
// should write a number between 1 and 5 (but node will wait until the end of all promises before exiting)
Promise.any(arr).then((d) => console.log(d)).catch((error) => console.error(error));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment