如何基于流逝时间实现方法执行次数限制,是否有相关实现框架?
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
相关产品推荐
相关产品推荐

