All files / async sleep.ts

100% Statements 12/12
100% Branches 5/5
100% Functions 5/5
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  3x 3x                             5x 5x 1x 1x   4x 2x 2x     2x 2x   4x      
function abortReason(signal: AbortSignal): Error {
  const reason: unknown = signal.reason;
  return reason instanceof Error ? reason : new Error(String(reason));
}
 
/**
 * Waits for a delay, cancellable with an `AbortSignal` that clears the timer.
 *
 * @param ms - The delay in milliseconds. Defaults to `0`.
 * @param signal - The signal that cancels the wait.
 * @returns A promise resolved once the delay has elapsed.
 * @rejects {Error} With the signal's reason when `signal` is aborted.
 * @example
 * await sleep(100);
 * await sleep(1000, controller.signal); // rejects as soon as controller.abort() is called
 */
export async function sleep(ms = 0, signal?: AbortSignal): Promise<void> {
  return new Promise<void>((resolve, reject) => {
    if (signal?.aborted === true) {
      reject(abortReason(signal));
      return;
    }
    const timer = setTimeout(() => {
      signal?.removeEventListener('abort', onAbort);
      resolve();
    }, ms);
    function onAbort(this: AbortSignal): void {
      clearTimeout(timer);
      reject(abortReason(this));
    }
    signal?.addEventListener('abort', onAbort, { once: true });
  });
}