UNPKG

remix-utils-rt

Version:

This package contains simple utility functions to use with [React Router](https://reactrouter.com/home).

111 lines 3.02 kB
/** * Get a hash of promises and await them all. * Then return the same hash with the resolved values. * @example * export async function loader({ request }: LoaderFunctionArgs) { * return json( * promiseHash({ * user: getUser(request), * posts: getPosts(request), * }) * ); * } * @example * export async function loader({ request }: LoaderFunctionArgs) { * return json( * promiseHash({ * user: getUser(request), * posts: promiseHash({ * list: getPosts(request), * comments: promiseHash({ * list: getComments(request), * likes: getLikes(request), * }), * }), * }) * ); * } */ export async function promiseHash(hash) { return Object.fromEntries(await Promise.all(Object.entries(hash).map(async ([key, promise]) => [key, await promise]))); } /** * Used to uniquely identify a timeout * @private */ let TIMEOUT = Symbol("TIMEOUT"); /** * Attach a timeout to any promise, if the timeout resolves first ignore the * original promise and throw an error * @param promise The promise to attach a timeout to * @param options The options to use * @param options.ms The number of milliseconds to wait before timing out * @param options.controller An AbortController to abort the original promise * @returns The result of the promise * @throws TimeoutError If the timeout resolves first * @example * try { * let result = await timeout( * fetch("https://example.com"), * { ms: 100 } * ); * } catch (error) { * if (error instanceof TimeoutError) { * // Handle timeout * } * } * @example * try { * let controller = new AbortController(); * let result = await timeout( * fetch("https://example.com", { signal: controller.signal }), * { ms: 100, controller } * ); * } catch (error) { * if (error instanceof TimeoutError) { * // Handle timeout * } * } */ export async function timeout(promise, options) { let timer = null; try { let result = await Promise.race([ promise, new Promise((resolve) => { timer = setTimeout(() => resolve(TIMEOUT), options.ms); }), ]); if (timer) clearTimeout(timer); if (result === TIMEOUT) { if (options.controller) options.controller.abort(); throw new TimeoutError(`Timed out after ${options.ms}ms`); } return result; } catch (error) { if (timer) clearTimeout(timer); throw error; } } /** * An error thrown when a timeout occurs * @example * try { * let result = await timeout(fetch("https://example.com"), { ms: 100 }); * } catch (error) { * if (error instanceof TimeoutError) { * // Handle timeout * } * } */ export class TimeoutError extends Error { constructor(message) { super(message); this.name = "TimeoutError"; } } //# sourceMappingURL=promise.js.map