89

関数を何度も実行したいのですが、その間に遅延があります。Dartでこれを行うにはどうすればよいですか?

4

7 に答える 7

185

このクラスを使用して、Timerワンショットおよび繰り返し機能をスケジュールできます。

繰り返す

繰り返し関数を実行する方法は次のとおりです。

import 'dart:async';
main() {
  const oneSec = Duration(seconds:1);
  Timer.periodic(oneSec, (Timer t) => print('hi!'));
}

Timer は、期間と実行する関数の 2 つの引数を取ります。期間は のインスタンスである必要がありますDuration。コールバックは、単一のパラメーター (タイマー自体) を取る必要があります。

繰り返しタイマーのキャンセル

timer.cancel()繰り返しタイマーをキャンセルするために使用します。これが、繰り返しタイマーからコールバック実行にタイマーが渡される理由の 1 つです。


遅れてワンショット

遅延後にワンショット関数をスケジュールするには (一度実行し、将来のある時点で):

import 'dart:async';
main() {
  const twentyMillis = Duration(milliseconds:20);
  Timer(twentyMillis, () => print('hi!'));
}

ワンショット タイマーのコールバックはパラメーターを取らないことに注意してください。


できるだけ早くワンショット

また、関数ができるだけ早く実行されるように要求することもできます。少なくとも 1 つのイベント ループ ティックの後に実行されます。

import 'dart:async';
main() {
  Timer.run(() => print('hi!'));
}

HTMLで

タイマーは HTML でも機能します。実際にwindow.setTimeoutは が削除されたため、Timer は今後関数を実行する唯一の方法です。

于 2013-02-18T21:55:44.953 に答える
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 に答える
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 に答える