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

asyncRateLimit

Function: asyncRateLimit()

ts
function asyncRateLimit<TFn>(fn, initialOptions): (...args) => Promise<undefined | ReturnType<TFn>>
function asyncRateLimit<TFn>(fn, initialOptions): (...args) => Promise<undefined | ReturnType<TFn>>

Defined in: async-rate-limiter.ts:447

Creates an async rate-limited function that will execute the provided function up to a maximum number of times within a time window.

Unlike the non-async rate limiter, 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.

Note that rate limiting is a simpler form of execution control compared to throttling or debouncing:

  • A rate limiter will allow all executions until the limit is reached, then block all subsequent calls until the window resets
  • A throttler ensures even spacing between executions, which can be better for consistent performance
  • A debouncer collapses multiple calls into one, which is better for handling bursts of events

State Management:

  • Uses TanStack Store for reactive state management
  • Use initialState to provide initial state values when creating the rate limiter
  • initialState can be a partial state object
  • Use onSuccess callback to react to successful function execution and implement custom logic
  • Use onError callback to react to function execution errors and implement custom error handling
  • Use onSettled callback to react to function execution completion (success or error) and implement custom logic
  • Use onReject callback to react to executions being rejected when rate limit is exceeded
  • The state includes execution times, success/error counts, and current execution status
  • State can be accessed via the underlying AsyncRateLimiter instance's store.state property
  • When using framework adapters (React/Solid), state is accessed from the hook's state property

Consider using throttle() or debounce() if you need more intelligent execution control. Use rate limiting when you specifically need to enforce a hard limit on the number of executions within a time period.

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

initialOptions

AsyncRateLimiterOptions<TFn>

Returns

Function

Attempts to execute the rate-limited function if within the configured limits. Will reject execution if the number of calls in the current window exceeds the limit.

Error Handling:

  • If the rate-limited function throws and no onError handler is configured, the error will be thrown from this method.
  • If an onError handler is configured, errors will be caught and passed to the handler, and this method will return undefined.
  • The error state can be checked using getErrorCount() and getIsExecuting().

Parameters

args

...Parameters<TFn>

Returns

Promise<undefined | ReturnType<TFn>>

A promise that resolves with the function's return value, or undefined if an error occurred and was handled by onError

Throws

The error from the rate-limited function if no onError handler is configured

Example

ts
const rateLimiter = new AsyncRateLimiter(fn, { limit: 5, window: 1000 });

// First 5 calls will return a promise that resolves with the result
const result = await rateLimiter.maybeExecute('arg1', 'arg2');

// Additional calls within the window will return undefined
const result2 = await rateLimiter.maybeExecute('arg1', 'arg2'); // undefined
const rateLimiter = new AsyncRateLimiter(fn, { limit: 5, window: 1000 });

// First 5 calls will return a promise that resolves with the result
const result = await rateLimiter.maybeExecute('arg1', 'arg2');

// Additional calls within the window will return undefined
const result2 = await rateLimiter.maybeExecute('arg1', 'arg2'); // undefined

Example

ts
// Rate limit to 5 calls per minute with a sliding window
const rateLimited = asyncRateLimit(makeApiCall, {
  limit: 5,
  window: 60000,
  windowType: 'sliding',
  onError: (error) => {
    console.error('API call failed:', error);
  },
  onReject: (rateLimiter) => {
    console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
  }
});

// First 5 calls will execute immediately
// Additional calls will be rejected until the minute window resets
// Returns the API response directly
const result = await rateLimited();

// For more even execution, consider using throttle instead:
const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds
// Rate limit to 5 calls per minute with a sliding window
const rateLimited = asyncRateLimit(makeApiCall, {
  limit: 5,
  window: 60000,
  windowType: 'sliding',
  onError: (error) => {
    console.error('API call failed:', error);
  },
  onReject: (rateLimiter) => {
    console.log(`Rate limit exceeded. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
  }
});

// First 5 calls will execute immediately
// Additional calls will be rejected until the minute window resets
// Returns the API response directly
const result = await rateLimited();

// For more even execution, consider using throttle instead:
const throttled = throttle(makeApiCall, { wait: 12000 }); // One call every 12 seconds
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.