Skip to main content
Creates an async-aware throttled function that only invokes fn at most once per intervalMs milliseconds.

Signature

function throttle<Args extends unknown[], R>(
  fn: (...args: Args) => PromiseLike<R> | R,
  intervalMs: number,
  options?: StandardOptions,
): (...args: Args) => Promise<R>

Parameters

fn
(...args: Args) => PromiseLike<R> | R
required
The function to throttle. Can be sync or async.
intervalMs
number
required
The minimum interval between invocations in milliseconds.
options
StandardOptions
Throttle configuration options.

Returns

A throttled version of the function that returns a promise.

Examples

Basic throttle

import { throttle } from '@temelj/async';

const handleScroll = throttle(async () => {
  await updateScrollPosition();
}, 100);

window.addEventListener('scroll', handleScroll);

API rate limiting

import { throttle } from '@temelj/async';

const fetchData = throttle(async (id: string) => {
  const response = await fetch(`/api/data/${id}`);
  return await response.json();
}, 1000);

// Only makes 1 request per second maximum
await fetchData('1');
await fetchData('2'); // Waits for interval
await fetchData('3'); // Waits for interval

Mouse movement tracking

import { throttle } from '@temelj/async';

const trackMouse = throttle(async (x: number, y: number) => {
  await analytics.trackEvent('mouse_move', { x, y });
}, 500);

document.addEventListener('mousemove', (e) => {
  trackMouse(e.clientX, e.clientY);
});

With abort signal

import { throttle } from '@temelj/async';

const controller = new AbortController();

const saveProgress = throttle(
  async (progress: number) => {
    await api.updateProgress(progress);
  },
  2000,
  { signal: controller.signal }
);

saveProgress(25);
saveProgress(50);
saveProgress(75);

// Cancel pending saves
controller.abort();

Build docs developers (and LLMs) love