Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

defer

Defers the execution of a function until the next event loop tick.

TypeScript
Copied!
1/**
2 * Defers the execution of a function until the next event loop tick.
3 *
4 * @param fn - The function to execute later.
5 *
6 * @example
7 * defer(() => console.log('This runs after current stack is done.'));
8 */
9export function defer(fn: () => void): void {
10  Promise.resolve().then(fn);
11}
  • Microtask Scheduling

    Uses Promise.resolve().then(...) to defer execution to the next microtask queue, ensuring the function runs after the current call stack clears.

  • Minimal Overhead

    Extremely lightweight and efficient, with no timers or additional dependencies.

  • Non-Blocking Behavior

    Ensures that deferred functions do not interfere with synchronous execution, making them ideal for post-processing.

  • Cross-Environment Compatibility

    Works reliably in both browser and Node.js environments, as Promise-based microtasks are universally supported.

Tests | Examples

TypeScript
Copied!
1jest.useFakeTimers();
2
3test('defer - executes after current call stack', () => {
4  const mockFn = jest.fn();
5
6  defer(mockFn);
7
8  // Immediately after defer, function should not have been called
9  expect(mockFn).not.toHaveBeenCalled();
10
11  // Run all microtasks
12  return Promise.resolve().then(() => {
13    expect(mockFn).toHaveBeenCalledTimes(1);
14  });
15});
16
17test('defer - multiple calls are executed in order', () => {
18  const calls: number[] = [];
19
20  defer(() => calls.push(1));
21  defer(() => calls.push(2));
22  defer(() => calls.push(3));
23
24  return Promise.resolve().then(() => {
25    expect(calls).toEqual([1, 2, 3]);
26  });
27});

Common Use Cases

  • UI Update Deferral

    Postpone logic (e.g., DOM reads/writes) until after React or Vue state updates flush.

  • Sequencing After Synchronous Work

    Defer actions like logging, cleanup, or notification dispatch until after the current function completes.

  • Task Scheduling in Tests

    Delay execution of assertions or callbacks until after setup code runs.

  • Event Handling Optimizations

    Avoid blocking UI threads by deferring expensive operations triggered by events.

  • Safe Cleanup

    Defer teardown steps that must occur after all synchronously scheduled operations have completed.

Codebase: Utilities -> Functions -> defer | Yevhen Klymentiev