Framework
Version
Debouncer API Reference
Throttler API Reference
Rate Limiter API Reference
Queue API Reference

useAsyncRateLimiter

Function: useAsyncRateLimiter()

ts
function useAsyncRateLimiter<TFn>(fn, options): AsyncRateLimiter<TFn>
function useAsyncRateLimiter<TFn>(fn, options): AsyncRateLimiter<TFn>

Defined in: react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:67

A low-level React hook that creates an AsyncRateLimiter instance to limit how many times an async function can execute within a time window.

This hook is designed to be flexible and state-management agnostic - it simply returns a rate limiter instance that you can integrate with any state management solution (useState, Redux, Zustand, Jotai, etc).

Rate limiting allows an async function to execute up to a specified limit within a time window, then blocks subsequent calls until the window passes. This is useful for respecting API rate limits, managing resource constraints, or controlling bursts of async operations.

Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function, making it ideal for API calls and other async operations where you want the result of the maybeExecute call instead of setting the result on a state variable from within the rate-limited function.

The rate limiter supports two types of windows:

  • 'fixed': A strict window that resets after the window period. All executions within the window count towards the limit, and the window resets completely after the period.
  • 'sliding': A rolling window that allows executions as old ones expire. This provides a more consistent rate of execution over time.

Error Handling:

  • If an onError handler is provided, it will be called with the error and rate limiter instance
  • If throwOnError is true (default when no onError handler is provided), the error will be thrown
  • If throwOnError is false (default when onError handler is provided), the error will be swallowed
  • Both onError and throwOnError can be used together - the handler will be called before any error is thrown
  • The error state can be checked using the underlying AsyncRateLimiter instance
  • Rate limit rejections (when limit is exceeded) are handled separately from execution errors via the onReject handler

Type Parameters

TFn extends AnyAsyncFunction

Parameters

fn

TFn

options

AsyncRateLimiterOptions<TFn>

Returns

AsyncRateLimiter<TFn>

Example

tsx
// Basic API call rate limiting with return value
const { maybeExecute } = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data; // Return value is preserved
  },
  { limit: 5, window: 1000 } // 5 calls per second
);

// With state management and return value
const [data, setData] = useState(null);
const { maybeExecute } = useAsyncRateLimiter(
  async (query) => {
    const result = await searchAPI(query);
    setData(result);
    return result; // Return value can be used by the caller
  },
  {
    limit: 10,
    window: 60000, // 10 calls per minute
    onReject: (rateLimiter) => {
      console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
    },
    onError: (error) => {
      console.error('API call failed:', error);
    }
  }
);
// Basic API call rate limiting with return value
const { maybeExecute } = useAsyncRateLimiter(
  async (id: string) => {
    const data = await api.fetchData(id);
    return data; // Return value is preserved
  },
  { limit: 5, window: 1000 } // 5 calls per second
);

// With state management and return value
const [data, setData] = useState(null);
const { maybeExecute } = useAsyncRateLimiter(
  async (query) => {
    const result = await searchAPI(query);
    setData(result);
    return result; // Return value can be used by the caller
  },
  {
    limit: 10,
    window: 60000, // 10 calls per minute
    onReject: (rateLimiter) => {
      console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
    },
    onError: (error) => {
      console.error('API call failed:', error);
    }
  }
);
Subscribe to Bytes

Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.

Bytes

No spam. Unsubscribe at any time.