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

异步速率限制器

类: AsyncRateLimiter<TFn>

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

一个创建异步速率限制函数的类。

速率限制是一种简单的方法,它允许一个函数在一个时间窗口内执行最多达到一个限制,然后阻止所有后续调用,直到窗口过去。这可能导致“爆发式”行为,即所有执行立即发生,然后是完全的阻塞。

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

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

与非异步的 RateLimiter 不同,这个异步版本支持从速率限制的函数返回值的,使其非常适合 API 调用和其他异步操作,你希望在 maybeExecute 调用中获得结果,而不是在速率限制函数内部将结果设置到状态变量中。

为了更平滑的执行模式,请考虑使用

  • 节流 (Throttling): 确保执行之间有规律的间隔(例如,最多每 200 毫秒一次)
  • 防抖 (Debouncing): 在调用暂停后执行(例如,在没有调用 500 毫秒后)

速率限制最适合用于硬性的 API 限制或资源约束。对于 UI 更新或平滑频繁的事件,节流或防抖通常能提供更好的用户体验。

状态管理

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

错误处理

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

示例

ts
const rateLimiter = new AsyncRateLimiter(
  async (id: string) => await api.getData(id),
  {
    limit: 5,
    window: 1000,
    windowType: 'sliding',
    onError: (error) => {
      console.error('API call failed:', error);
    },
    onReject: (limiter) => {
      console.log(`Rate limit exceeded. Try again in ${limiter.getMsUntilNextWindow()}ms`);
    }
  }
);

// Will execute immediately until limit reached, then block
// Returns the API response directly
const data = await rateLimiter.maybeExecute('123');
const rateLimiter = new AsyncRateLimiter(
  async (id: string) => await api.getData(id),
  {
    limit: 5,
    window: 1000,
    windowType: 'sliding',
    onError: (error) => {
      console.error('API call failed:', error);
    },
    onReject: (limiter) => {
      console.log(`Rate limit exceeded. Try again in ${limiter.getMsUntilNextWindow()}ms`);
    }
  }
);

// Will execute immediately until limit reached, then block
// Returns the API response directly
const data = await rateLimiter.maybeExecute('123');

类型参数

TFn extends AnyAsyncFunction

构造函数

new AsyncRateLimiter()

ts
new AsyncRateLimiter<TFn>(fn, initialOptions): AsyncRateLimiter<TFn>
new AsyncRateLimiter<TFn>(fn, initialOptions): AsyncRateLimiter<TFn>

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

参数

fn

TFn

initialOptions

AsyncRateLimiterOptions<TFn>

Returns (返回)

AsyncRateLimiter<TFn>

属性

fn

ts
fn: TFn;
fn: TFn;

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


key

ts
key: string;
key: string;

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


options

ts
options: AsyncRateLimiterOptions<TFn>;
options: AsyncRateLimiterOptions<TFn>;

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


store

ts
readonly store: Store<Readonly<AsyncRateLimiterState<TFn>>>;
readonly store: Store<Readonly<AsyncRateLimiterState<TFn>>>;

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

方法

getMsUntilNextWindow()

ts
getMsUntilNextWindow(): number
getMsUntilNextWindow(): number

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

返回下一次执行可能发生前的毫秒数。对于固定窗口,这是当前窗口重置之前的时间;对于滑动窗口,这是最旧的执行过期之前的时间。

Returns (返回)

number


getRemainingInWindow()

ts
getRemainingInWindow(): number
getRemainingInWindow(): number

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

返回当前窗口中允许的剩余执行次数

Returns (返回)

number


maybeExecute()

ts
maybeExecute(...args): Promise<undefined | ReturnType<TFn>>
maybeExecute(...args): Promise<undefined | ReturnType<TFn>>

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

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

错误处理

  • 如果速率限制的函数抛出错误且未配置 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

reset()

ts
reset(): void
reset(): void

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

重置速率限制器状态

Returns (返回)

void


setOptions()

ts
setOptions(newOptions): void
setOptions(newOptions): void

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

更新异步速率限制器选项

参数

newOptions

Partial<AsyncRateLimiterOptions<TFn>>

Returns (返回)

void

我们的合作伙伴
Code Rabbit
Unkey
订阅 Bytes

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

Bytes

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

订阅 Bytes

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

Bytes

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