or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Delay

Delay is a lightweight Promise-based utility for delaying execution in JavaScript applications. It provides precise timing control with support for AbortController cancellation, value resolution, random delays, and custom timeout implementations for testing scenarios.

Package Information

  • Package Name: delay
  • Package Type: npm
  • Language: JavaScript with TypeScript definitions
  • Installation: npm install delay

Core Imports

import delay from 'delay';
import { rangeDelay, clearDelay, createDelay } from 'delay';

For CommonJS:

const delay = require('delay');
const { rangeDelay, clearDelay, createDelay } = require('delay');

Basic Usage

import delay from 'delay';

// Basic delay
bar();
await delay(100);
// Executed 100 milliseconds later
baz();

// Delay with resolved value
const result = await delay(100, { value: '🦄' });
console.log(result); //=> '🦄'

// Cancellable delay
const abortController = new AbortController();
setTimeout(() => abortController.abort(), 500);

try {
  await delay(1000, { signal: abortController.signal });
} catch (error) {
  console.log(error.name); //=> 'AbortError'
}

Architecture

Delay is built around several key design patterns:

  • Promise-based API: All delay functions return native Promises for seamless integration with async/await and Promise chains
  • AbortController Integration: Native cancellation support through standard AbortSignal interface, enabling cooperative cancellation
  • Factory Pattern: createDelay allows custom timer implementations for testing environments or specialized use cases
  • Weak Map Tracking: Internal promise-to-cleanup mapping using WeakMap prevents memory leaks and enables clearDelay functionality
  • Timer Abstraction: Customizable setTimeout/clearTimeout implementations allow stubbing for tests or alternative scheduling

The package maintains minimal overhead while providing maximum flexibility through these architectural choices.

Capabilities

Basic Delay

Creates a Promise that resolves after a specified number of milliseconds.

/**
 * Create a promise which resolves after the specified milliseconds
 * @param milliseconds - Milliseconds to delay the promise (0 for next tick)
 * @param options - Configuration options
 * @returns Promise that resolves with the provided value after the delay
 */
function delay<T>(milliseconds: number, options?: Options<T>): Promise<T>;

Note: While the TypeScript definition requires the milliseconds parameter, the runtime implementation treats undefined as 0, allowing delay() to work in plain JavaScript. In TypeScript, use delay(0) for next-tick behavior.

Usage Examples:

// Simple delay
await delay(1000); // Wait 1 second

// Delay with 0ms (next tick) - note: TypeScript requires explicit 0
await delay(0);

// Delay with value
const greeting = await delay(500, { value: 'Hello!' });
console.log(greeting); //=> 'Hello!'

// Cancellable delay
const controller = new AbortController();
const delayPromise = delay(2000, { 
  value: 'Done',
  signal: controller.signal 
});

// Cancel after 1 second
setTimeout(() => controller.abort(), 1000);

try {
  await delayPromise;
} catch (error) {
  console.log(error.name); //=> 'AbortError'
}

Random Range Delay

Creates a Promise that resolves after a random number of milliseconds between minimum and maximum values.

/**
 * Create a promise which resolves after a random amount of milliseconds
 * @param minimum - Minimum amount of milliseconds to delay the promise
 * @param maximum - Maximum amount of milliseconds to delay the promise
 * @param options - Configuration options
 * @returns Promise that resolves after a random delay between minimum and maximum
 */
function rangeDelay<T>(minimum: number, maximum: number, options?: Options<T>): Promise<T>;

Usage Examples:

// Random delay between 100-500ms
await rangeDelay(100, 500);

// Random delay with value
const result = await rangeDelay(50, 150, { value: 'random!' });

// Random delay with abort signal
const controller = new AbortController();
await rangeDelay(200, 800, { signal: controller.signal });

Clear Delay

Immediately clears a delay and resolves the promise with its intended value.

/**
 * Clears the delay and settles the promise
 * @param delayPromise - The delay promise to clear
 * @returns void
 */
function clearDelay(delayPromise: Promise<unknown>): void;

Usage Examples:

const delayPromise = delay(1000, { value: 'Done' });

// Clear after 500ms instead of waiting 1000ms
setTimeout(() => {
  clearDelay(delayPromise);
}, 500);

// Still resolves with 'Done' but much faster
console.log(await delayPromise); //=> 'Done'

// Safe to call on non-delay promises (does nothing)
clearDelay(Promise.resolve('not a delay'));

Custom Delay Factory

Creates a new delay function using custom setTimeout and clearTimeout implementations.

/**
 * Creates a new delay instance using provided timer functions
 * @param timers - Object with custom timer implementations
 * @param timers.setTimeout - Custom setTimeout function
 * @param timers.clearTimeout - Custom clearTimeout function  
 * @returns New delay function with same signature as default delay
 */
function createDelay(timers: {
  clearTimeout: (timeoutId: any) => void;
  setTimeout: (callback: (...args: any[]) => void, milliseconds: number, ...args: any[]) => unknown;
}): typeof delay;

Usage Examples:

// Useful for testing with fake timers
import { createDelay } from 'delay';

const customDelay = createDelay({ 
  setTimeout: myMockSetTimeout, 
  clearTimeout: myMockClearTimeout 
});

// Use like normal delay but with custom timer implementation
await customDelay(100, { value: 'test' });

// Node.js example with unref to prevent hanging
const unrefDelay = createDelay({
  clearTimeout,
  setTimeout(...args) {
    return setTimeout(...args).unref();
  }
});

Options

interface Options<T> {
  /**
   * A value to resolve in the returned promise
   */
  value?: T;

  /**
   * An AbortSignal to abort the delay
   * The returned promise will be rejected with an AbortError if aborted
   */
  signal?: AbortSignal;
}

Error Handling

The delay functions can throw the following errors:

  • AbortError: Thrown when a delay is cancelled using an AbortSignal
    • error.name will be 'AbortError'
    • error.message will be 'Delay aborted'
try {
  const controller = new AbortController();
  controller.abort(); // Abort immediately
  
  await delay(1000, { signal: controller.signal });
} catch (error) {
  console.log(error.name);    //=> 'AbortError'
  console.log(error.message); //=> 'Delay aborted'
}

Browser and Node.js Compatibility

  • Node.js: Requires Node.js 16 or later
  • Browser: Works in all modern browsers with Promise and AbortController support
  • ES Modules: Uses native ES module syntax
  • CommonJS: Also available via require() for compatibility
  • TypeScript: Full TypeScript definitions included

The package uses standard setTimeout and clearTimeout by default, making it compatible across environments. Custom timer implementations can be provided via createDelay for testing or specialized use cases.