export async function fetchAbortable(
url: string,
opts: RequestInit & { timeoutMs?: number } = {},
): Promise<Response> {
const { timeoutMs, signal: externalSignal, ...rest } = opts;
const ctl = new AbortController();
const onAbort = () => ctl.abort(externalSignal?.reason);
externalSignal?.addEventListener('abort', onAbort, { once: true });
const timeoutId = timeoutMs
? setTimeout(() => ctl.abort(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs)
: undefined;
try {
return await fetch(url, { ...rest, signal: ctl.signal });
} finally {
if (timeoutId) clearTimeout(timeoutId);
externalSignal?.removeEventListener('abort', onAbort);
}
}
const ctl = new AbortController();
const resp = await fetchAbortable('/api/slow', { signal: ctl.signal, timeoutMs: 5000 });
Create a free account and build your private vault. Share publicly whenever you want.