我想一遍又一遍地运行一个函数,中间有一个延迟。我怎样才能用 Dart 做到这一点?
7 回答
您可以使用Timer
该类来安排一次性和重复功能。
重复
以下是运行重复函数的方法:
import 'dart:async';
main() {
const oneSec = Duration(seconds:1);
Timer.periodic(oneSec, (Timer t) => print('hi!'));
}
Timer 有两个参数,一个持续时间和一个运行函数。持续时间必须是 的实例Duration
。回调必须采用单个参数,即计时器本身。
取消重复计时器
用于timer.cancel()
取消重复计时器。这就是为什么将计时器从重复计时器传递给回调运行的原因之一。
延迟后的一击
在延迟后安排一次性功能(执行一次,在将来的某个时间执行):
import 'dart:async';
main() {
const twentyMillis = Duration(milliseconds:20);
Timer(twentyMillis, () => print('hi!'));
}
请注意,一次性计时器的回调不带参数。
尽快一击
您还可以要求尽快运行一个函数,至少在未来一个事件循环滴答声。
import 'dart:async';
main() {
Timer.run(() => print('hi!'));
}
在 HTML 中
计时器甚至可以在 HTML 中使用。事实上,window.setTimeout
被删除了,所以 Timer 是以后运行函数的唯一方法。
5 秒定时器示例
bool isStopped = false; //global
sec5Timer() {
Timer.periodic(Duration(seconds: 5), (timer) {
if (isStopped) {
timer.cancel();
}
print("Dekhi 5 sec por por kisu hy ni :/");
});
}
从任何函数调用
sec5Timer();
停止任何功能
isStopped = true;
要处理,您可以使用此代码或技术。
@override
void initState() {
_timer = new Timer.periodic(widget.refreshRate,
(Timer timer) => _updateDisplayTime(inheritedWidget));
super.initState();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
https://api.dartlang.org/stable/1.24.3/dart-async/Stream/Stream.periodic.html
import 'dart:async';
StreamSubscription periodicSub;
void main() {
periodicSub = new Stream.periodic(const Duration(milliseconds: 500), (v) => v)
.take(10)
.listen((count) => print('tick $count'));
}
或者如果不需要计数器
import 'dart:async';
StreamSubscription periodicSub;
void main() {
periodicSub = new Stream.periodic(const Duration(milliseconds: 500))
.take(10)
.listen((_) => print('tick'));
}
您还可以使用 Future.delayed 和 await 来延迟执行:
Future<Null> delay(int milliseconds) {
return new Future.delayed(new Duration(milliseconds: milliseconds));
}
main() async {
await delay(500);
print('Delayed 500 milliseconds');
}
替代品;
import 'dart:async';
Timer interval(Duration duration, func) {
Timer function() {
Timer timer = new Timer(duration, function);
func(timer);
return timer;
}
return new Timer(duration, function);
}
void main() {
int i = 0;
interval(new Duration(seconds: 1), (timer) {
print(i++);
if (i > 5) timer.cancel();
});
}
与 Timer.periodic 和 Stream.periodic 相反,发布我最喜欢的处理此类任务的方式。优点:
- 第一个循环立即运行
- 回调可以工作比间隔更长的时间而没有任何重入头痛
Completer<bool> periodic(Duration interval, Function(int cycle) callback) {
final done = Completer<bool>();
() async {
var cycle = 0;
while (!done.isCompleted) {
try {
await callback(cycle);
} catch (e, s) {
log("$e", stackTrace: s);
}
cycle++;
await done.future
.timeout(interval)
.onError((error, stackTrace) => null);
}
}();
return done;
}
main() {
final task = periodic(Duration(seconds: 10), (cycle) async {
/// do the periodic tasks here
});
/// main code here
/// and when going to stop the above periodic call
task.complete(true);
}
与 JavaScript 功能相同的代码(setInterval、setTimeout、clearInterval 和 clearTimeout):
// ------------------------------
// Import:
import 'dart:async';
// ------------------------------
// Definitions:
void clearTimeout(Timer timer) {
try {
timer.cancel();
} catch (e) {}
}
Timer setTimeout(VoidCallback fn, int millis) {
Timer timer;
if (millis > 0)
timer = new Timer(new Duration(milliseconds: millis), fn);
else
fn();
return timer;
}
void clearInterval(Timer timer) {
try {
timer.cancel();
} catch (e) {}
}
Timer setInterval(VoidCallback fn, int millis) {
Timer timer;
if (millis > 0)
timer = new Timer.periodic(new Duration(milliseconds: millis), (timer) {
fn();
});
else
fn(); // If millis input is too low, only run function once and stop
return timer;
}
// ---------------------------------
// Example:
int myValue = 0;
Timer counter = setInterval((){ myValue++; }, 50);
setTimeout((){
clearInterval(counter);
}, 5000);