dart 中的节流函数执行
Posted
技术标签:
【中文标题】dart 中的节流函数执行【英文标题】:Throttle function execution in dart 【发布时间】:2019-04-05 10:14:16 【问题描述】:Dart
有没有办法像这样限制函数执行
Observable.throttle(myFunction,2000);
【问题讨论】:
thottle
或 debounce
from github.com/ReactiveX/rxdart 应该提供。 medium.com/fantageek/… 可能是相关的。
我不确定如何将这些信息与我所拥有的信息结合起来,听按钮是否对颤振有效?
在 Dart 中,要重复调用的函数通常是 Stream
上的侦听器 - 你在这里有 Stream
并且你试图限制传递给 @ 的函数987654330@?如果是这种情况,我们应该将其视为限制流而不是函数。为此使用values.transform(throttle(Duration(seconds: 2))).listen(myFunction)
。 pub.dartlang.org/packages/stream_transform 如果这不是 Stream 侦听器,您能否详细说明用例?你需要Function
可以作为参数传递吗?
我想限制函数执行,例如假设有一个按钮将向 api 发送请求,我希望该按钮始终可点击,但每次调用 1 次都会限制 api 调用例如 1 分钟,因此用户可以随意点击,但我每分钟只会发送一个请求。
您可以使用 StreamController 将函数调用转换为 Stream。 Mayberxdart Observable 提供了一些开箱即用的东西来做到这一点。
【参考方案1】:
使用https://pub.dartlang.org/documentation/rxdart/latest/rx/Observable/throttle.html
因此,您在 Dart 2 中使用 RxDart 的示例是
final subject = new ReplaySubject<int>();
myCaller(Event event)
subject.add(event);
subject
.throttle(Duration(seconds: 2))
.listen(myHandler);
【讨论】:
【参考方案2】:// you can run the code in dartpad: https://dartpad.dev/
typedef VoidCallback = dynamic Function();
class Throttler
Throttler(this.throttleGapInMillis);
final int throttleGapInMillis;
int lastActionTime;
void run(VoidCallback action)
if (lastActionTime == null)
action();
lastActionTime = DateTime.now().millisecondsSinceEpoch;
else
if (DateTime.now().millisecondsSinceEpoch - lastActionTime > (throttleGapInMillis ?? 500))
action();
lastActionTime = DateTime.now().millisecondsSinceEpoch;
void main()
var throttler = Throttler();
// var throttler = Throttler(throttleGapInMillis: 1000);
throttler.run(()
print("will print");
);
throttler.run(()
print("will not print");
);
Future.delayed(Duration(milliseconds: 500), ()
throttler.run(()
print("will print with delay");
);
);
【讨论】:
static int lastActionTime;
所以,如果你使用Throttler
类的多个实例,它们都将共享相同的lastActionTime
?
你是对的。我犯了一个错误。我顺便编辑一下答案。【参考方案3】:
按照 Günter Zöchbauer 的思路,您可以使用 StreamController
将函数调用转换为 Stream
。举例来说,假设myFunction
有一个int
返回值和一个int
参数。
import 'package:rxdart/rxdart.dart';
// This is just a setup for the example
Stream<int> timedMyFunction(Duration interval)
StreamController<int> controller;
Timer timer;
int counter = 0;
void tick(_)
counter++;
controller.add(myFunction(counter)); // Calling myFunction here
void startTimer()
timer = Timer.periodic(interval, tick);
void stopTimer()
if (timer != null)
timer.cancel();
timer = null;
controller = StreamController<int>(
onListen: startTimer,
onPause: stopTimer,
onResume: startTimer,
onCancel: stopTimer);
return controller.stream;
// Setting up a stream firing twice a second of the values of myFunction
var rapidStream = timedMyFunction(const Duration(milliseconds: 500));
// Throttling the stream to once in every two seconds
var throttledStream = rapidStream.throttleTime(Duration(seconds: 2)).listen(myHandler);
【讨论】:
【参考方案4】:import 'package:flutter/foundation.dart';
import 'dart:async';
// A simple class for throttling functions execution
class Throttler
@visibleForTesting
final int milliseconds;
@visibleForTesting
Timer? timer;
@visibleForTesting
static const kDefaultDelay = 2000;
Throttler(this.milliseconds = kDefaultDelay);
void run(VoidCallback action)
if (timer?.isActive ?? false) return;
timer?.cancel();
action();
timer = Timer(Duration(milliseconds: milliseconds), () );
void dispose()
timer?.cancel();
// How to use
void main()
var throttler = Throttler();
throttler.run(()
print("will print");
);
throttler.run(()
print("will not print");
);
Future.delayed(const Duration(milliseconds: 2000), ()
throttler.run(()
print("will print with delay");
);
);
throttler.dispose();
【讨论】:
以上是关于dart 中的节流函数执行的主要内容,如果未能解决你的问题,请参考以下文章