是否有相当于Observable.Throttle的Streams?如果不是 - 是否有任何合理优雅的方式来达到类似的效果?
答案 0 :(得分:3)
目前在流上没有这样的方法。已提交增强请求,您可以加注明星issue 8492。
但是,您可以使用where方法执行此操作。在下面的例子中,我定义了一个ThrottleFilter
类来忽略给定持续时间内的事件:
import 'dart:async';
class ThrottleFilter<T> {
DateTime lastEventDateTime = null;
final Duration duration;
ThrottleFilter(this.duration);
bool call(T e) {
final now = new DateTime.now();
if (lastEventDateTime == null ||
now.difference(lastEventDateTime) > duration) {
lastEventDateTime = now;
return true;
}
return false;
}
}
main() {
final sc = new StreamController<int>();
final stream = sc.stream;
// filter stream with ThrottleFilter
stream.where(new ThrottleFilter<int>(const Duration(seconds: 10)).call)
.listen(print);
// send ints to stream every second, but ThrottleFilter will give only one int
// every 10 sec.
int i = 0;
new Timer.repeating(const Duration(seconds:1), (t) { sc.add(i++); });
}
答案 1 :(得分:2)
rate_limit package提供Streams的限制和去抖动。
答案 2 :(得分:1)
以下版本更接近Observable.Throttle的作用:
class Throttle extends StreamEventTransformer {
final duration;
Timer lastTimer;
Throttle(millis) :
duration = new Duration(milliseconds : millis);
void handleData(event, EventSink<int> sink) {
if(lastTimer != null){
lastTimer.cancel();
}
lastTimer = new Timer(duration, () => sink.add(event));
}
}
main(){
//...
stream.transform(new Throttle(500)).listen((_) => print(_));
//..
}
答案 3 :(得分:0)
@Victor Savkin 的回答很好,但我总是尽量避免重新发明轮子。所以除非你真的只需要那个油门,否则我建议使用 RxDart 包。由于您正在处理 Streams 和其他反应式对象,RxDart 除了节流之外还有很多不错的东西可以提供。
我们可以通过多种方式实现 500 毫秒的节流:
ThrottleExtensions<T>
Stream<T>
扩展:stream.throttleTime(Duration(milliseconds: 500)).listen(print);
stream.transform(ThrottleStreamTransformer((_) => TimerStream(true, const Duration(milliseconds: 500)))).listen(print);
stream.debounceTime(Duration(milliseconds: 500)).listen(print);
在延迟方面存在一些细微的差异,但它们都是限制性的。有关 throttleTime
与 debounceTime
的示例,请参见 What is the difference between throttleTime vs debounceTime in RxJS and when to choose which?