框架
版本
防抖器 API 参考
节流器 API 参考
速率限制器 API 参考
队列 API 参考
批处理器 API 参考

异步速率限制

函数: asyncRateLimit()

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

定义于: async-rate-limiter.ts:539

创建一个异步限速函数,该函数在一个时间窗口内最多执行给定函数指定的次数。

与非异步限速器不同,此异步版本支持从限速函数返回结果,使其成为 API 调用和其他异步操作的理想选择,因为您想要的是 maybeExecute 调用的结果,而不是在限速函数内部将结果设置到状态变量中。

速率限制器支持两种类型的窗口

  • 'fixed': 一个严格的窗口,在窗口期后重置。窗口内的所有执行都会计入限制,并且窗口会在期满后完全重置。
  • 'sliding': 一个滚动窗口,允许在旧的执行过期时进行新的执行。这提供了更一致的执行速率。

请注意,限速是一种比节流或防抖更简单的执行控制形式。

  • 限速器将允许所有执行,直到达到限制,然后阻止所有后续调用,直到窗口重置。
  • 节流器确保执行之间均匀间隔,这对于一致的性能可能更好。
  • 防抖器将多个调用合并为一个,这对于处理事件突发更好。

状态管理

  • 使用 TanStack Store 进行响应式状态管理
  • 使用 initialState 在创建速率限制器时提供初始状态值
  • initialState 可以是一个部分状态对象。
  • 使用 onSuccess 回调函数来响应成功的函数执行并实现自定义逻辑
  • 使用 onError 回调函数来响应函数执行错误并实现自定义错误处理
  • 使用 onSettled 回调函数来响应函数执行完成(成功或失败)并实现自定义逻辑
  • 使用 onReject 回调函数来响应在超出速率限制时被拒绝的执行
  • 状态包括执行时间、成功/错误计数以及当前执行状态。
  • 可以通过底层 AsyncRateLimiter 实例的 store.state 属性访问状态。
  • 在使用框架适配器(React/Solid)时,状态从 hook 的 state 属性访问

如果您需要更智能的执行控制,请考虑使用 throttle() 或 debounce()。当您确实需要强制执行在特定时间段内的执行次数硬限制时,请使用限速。

错误处理

  • 如果提供了 onError 处理程序,它将使用错误和速率限制器实例被调用
  • 如果 throwOnError 为 true(当没有提供 onError 处理程序时的默认值),错误将被抛出
  • 如果 throwOnError 为 false(当提供 onError 处理程序时的默认值),错误将被吞没
  • onError 和 throwOnError 可以一起使用 - 在任何错误被抛出之前,处理程序都会被调用
  • 可以使用底层的 AsyncRateLimiter 实例检查错误状态
  • 速率限制拒绝(当超出限制时)与执行错误分开处理,通过 onReject 处理程序。

类型参数

TFn extends AnyAsyncFunction

参数

fn

TFn

initialOptions

AsyncRateLimiterOptions<TFn>

Returns (返回)

Function

尝试在配置的限制内执行速率限制函数。如果当前窗口中的调用次数超过限制,则会拒绝执行。

错误处理

  • 如果限速函数抛出异常且未配置 onError 处理程序,则错误将从该方法中抛出。
  • 如果配置了 onError 处理程序,错误将被捕获并传递给处理程序,并且此方法将返回 undefined。
  • 可以使用 getErrorCount()getIsExecuting() 检查错误状态。

参数

args

...Parameters<TFn>

Returns (返回)

Promise<undefined | ReturnType<TFn>>

一个 Promise,它会解析为函数的返回值,如果错误被 onError 处理,则返回 undefined

Throws

如果未配置 onError 处理程序,则限速函数中的错误。

示例

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

示例

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
我们的合作伙伴
Code Rabbit
Unkey
订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。

订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。