在dart中执行油门功能



Dart中有没有一种方法可以像一样限制函数的执行

Observable.throttle(myFunction,2000);

使用https://pub.dartlang.org/documentation/rxdart/latest/rx/Observable/throttle.html

所以,你在带有RxDart的Dart 2中的例子是

final subject = new ReplaySubject<int>();
myCaller(Event event) {
subject.add(event);
}
subject
.throttle(Duration(seconds: 2))
.listen(myHandler);
// 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");
});
});
}
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();
}

按照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) {
late 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);

注意:请注意throttleTime的额外参数。默认值为trailing=falseleading=true。如果您希望在节流期内保留最新样本,那么您更希望使用trailing: trueleading: false

以下是限制常规函数的代码:

class Throttler {
final int milliseconds;
int _lastActionTime;
int get _millisecondsSinceEpoch => DateTime.now().millisecondsSinceEpoch;
Throttler({required this.milliseconds})
: _lastActionTime = DateTime.now().millisecondsSinceEpoch;
void run(void Function() action) {
if (_millisecondsSinceEpoch - _lastActionTime > milliseconds) {
action();
_lastActionTime = _millisecondsSinceEpoch;
}
}
}

用法:

final throttler = Throttler(milliseconds: 100);
throttler.run(() => print('1'));
throttler.run(() => print('2'));
// only '1' is printed

最新更新