89

我想一遍又一遍地运行一个函数,中间有一个延迟。我怎样才能用 Dart 做到这一点?

4

7 回答 7

185

您可以使用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 是以后运行函数的唯一方法。

于 2013-02-18T21:55:44.953 回答
29

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();
  }
于 2020-01-02T16:50:13.330 回答
19

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'));
}
于 2018-03-29T13:26:21.173 回答
9

您还可以使用 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');
}
于 2018-03-03T17:11:20.980 回答
4

替代品

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();
  });
}
于 2018-07-04T17:38:23.690 回答
2

与 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);
}
于 2021-04-04T09:52:01.243 回答
0

与 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);
于 2020-06-08T10:47:46.480 回答