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

after

Creates a function that will invoke the given callback only after it has been called 'count' times.

TypeScript
Copied!
1/**
2 * Creates a function that will invoke the given callback only
3 * after it has been called 'count' times.
4 *
5 * Includes a .reset() method to restart the call count.
6 *
7 * @param count - Number of calls before the callback is triggered.
8 * @param fn - The function to call after the threshold is reached.
9 * @returns A function with a reset() method.
10 */
11export function after(count: number, fn: () => void): (() => void) & { reset: () => void } {
12  let calls = 0;
13
14  const wrapper = () => {
15    calls++;
16    if (calls >= count) {
17      fn();
18    }
19  };
20
21  wrapper.reset = () => {
22    calls = 0;
23  };
24
25  return wrapper;
26}
  • Threshold-Based Invocation

    Defers execution of a callback until it has been triggered a specified number of times, allowing controlled batching or grouping.

  • Stateful Execution Logic

    Internally tracks call count, eliminating the need for external counters or flags.

  • Resettable Behavior

    Provides a .reset() method to restart the internal counter, making it reusable across scenarios or iterations.

  • Simple and Predictable

    Minimal implementation with transparent control flow makes it easy to understand and maintain.

Tests | Examples

TypeScript
Copied!
1test('after - invokes callback only after specified count', () => {
2  const spy = jest.fn();
3  const fn = after(3, spy);
4
5  fn(); // 1
6  fn(); // 2
7  expect(spy).not.toHaveBeenCalled();
8
9  fn(); // 3
10  expect(spy).toHaveBeenCalledTimes(1);
11
12  fn(); // 4
13  fn(); // 5
14  expect(spy).toHaveBeenCalledTimes(3);
15});
16
17test('after - reset() restarts the counter', () => {
18  const spy = jest.fn();
19  const fn = after(2, spy);
20
21  fn(); // 1
22  fn(); // 2 -> trigger
23  expect(spy).toHaveBeenCalledTimes(1);
24
25  fn.reset();
26  fn(); // 1 again
27  fn(); // 2 again -> trigger
28  expect(spy).toHaveBeenCalledTimes(2);
29});
30
31test('after - calls immediately if count is 0 or less', () => {
32  const spy = jest.fn();
33  const fn = after(0, spy);
34
35  fn();
36  expect(spy).toHaveBeenCalledTimes(1);
37
38  fn();
39  expect(spy).toHaveBeenCalledTimes(2);
40});

Common Use Cases

  • Asynchronous Coordination

    Run a final callback only after multiple independent async tasks (e.g., file loads, network calls) have completed.

  • Testing and Teardown Logic

    Wait for multiple assertions or cleanup steps to finish before continuing a test or releasing resources.

  • UI or Form Completion Checks

    Trigger an action after multiple form fields, validation steps, or user interactions are completed.

  • Batching Event Responses

    Fire a response after a defined number of repeated actions (e.g., keyboard input, game mechanics).

  • Debounced Group Completion

    Accumulate a certain number of actions before committing changes, submitting forms, or triggering updates.

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