Created
December 1, 2022 20:16
-
-
Save doronguttman/aeeb50312773448cd1121da51a1d164a to your computer and use it in GitHub Desktop.
Promise.raceTo (race with predicate)
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
interface PromiseConstructor { | |
/** | |
* Creates a Promise that is resolved with the value of the first resolved Promise that matches the predicate or rejected if any of the Promises are rejected. | |
* @param promises An array of Promises. | |
* @param [predicate] Optional. A function that is called with the result of each Promise. If the function returns true, the Promise is considered to be resolved. If no predicate is provided, the first truthy resolved Promise is returned. | |
* @returns A new Promise which is resolved with the value of the first resolved Promise that matches the predicate. | |
*/ | |
raceTo<T extends readonly unknown[] | []>(promises: T, predicate?: (result: Awaited<T[number]>) => boolean): Promise<Awaited<T[number]> | undefined>; | |
} | |
Promise.raceTo ??= function raceTo<T extends readonly unknown[] | []>(promises: T, predicate: (result: Awaited<T[number]>) => boolean = (result) => !!result): Promise<Awaited<T[number]> | undefined> { | |
return new Promise<Awaited<T[number]> | undefined>(async (resolve, reject) => { | |
try { | |
await Promise.allSettled( | |
promises.map(async (promise: T[number]) => { | |
try { | |
const result = await promise; | |
if (predicate(result)) { | |
resolve(result); | |
} | |
} catch (error) { | |
reject(error instanceof Error ? error : new AggregateError([error])); | |
} | |
}) | |
); | |
} finally { | |
resolve(undefined); | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment