You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于流逝时间实现方法执行次数限制,是否有相关实现框架?

Dart 每分钟执行次数限制解决方案

方案一:使用专用速率限制包

你可以直接使用社区提供的限流专用包,比如rate_limiter、throttling,这类包原生支持按时间窗口设置最大执行次数,可直接满足你的需求,不需要自己实现底层逻辑。

方案二:手动实现轻量执行限制器

如果不想引入额外依赖,可直接实现自定义的ExecutionLimiter类,代码如下:

import 'dart:async';

class ExecutionLimiter {
  final int maxExecutions;
  final Duration windowDuration;
  final List<DateTime> _executionTimestamps = [];
  final _waitQueue = <Completer>[];

  ExecutionLimiter({required this.maxExecutions, required this.windowDuration});

  Future<T> add<T>(FutureOr<T> Function() task) async {
    // 等待直到当前窗口有可用名额
    await _waitForAvailableSlot();
    // 记录当前执行时间
    _executionTimestamps.add(DateTime.now());
    try {
      return await task();
    } finally {
      // 执行完后处理下一个等待的任务
      _processWaitQueue();
    }
  }

  Future<void> _waitForAvailableSlot() {
    // 先清理超出时间窗口的历史记录
    final now = DateTime.now();
    _executionTimestamps.removeWhere((time) => now.difference(time) > windowDuration);
    
    if (_executionTimestamps.length < maxExecutions) {
      return Future.value();
    }
    // 没有可用名额则加入等待队列
    final completer = Completer();
    _waitQueue.add(completer);
    return completer.future;
  }

  void _processWaitQueue() {
    if (_waitQueue.isEmpty) return;
    // 清理过期记录后检查是否有空位
    final now = DateTime.now();
    _executionTimestamps.removeWhere((time) => now.difference(time) > windowDuration);
    if (_executionTimestamps.length < maxExecutions) {
      final nextCompleter = _waitQueue.removeAt(0);
      nextCompleter.complete();
    } else {
      // 计算最早的记录过期时间,到点再触发队列处理
      final earliestTime = _executionTimestamps.first;
      final waitTime = windowDuration - now.difference(earliestTime);
      Timer(waitTime, _processWaitQueue);
    }
  }
}

使用示例

完全匹配你期望的调用方式:

void main() async {
  final executer = ExecutionLimiter(maxExecutions: 100, windowDuration: Duration(minutes: 1));
  while (true) {
    // 自动按速率限制执行,不会超出API调用上限
    await executer.add(() => print('hello world'));
  }
}

该实现采用固定时间窗口计数逻辑,支持自定义最大执行次数、时间窗口长度,超出限制的任务会自动等待直到窗口出现可用名额,无需手动处理等待逻辑。

内容的提问来源于stack exchange,提问作者Jinairu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 03:45:04