Dart结束后重复一个功能

时间:2015-05-25 09:27:24

标签: dart

我有一个长时间运行的功能,可以进行一些后台处理。

当功能完成后,我想在短暂延迟后重复。

这样做的最佳方式是什么?

我最终得到了这个混乱的代码

  bool busy = false;
  new Timer.periodic(const Duration(minutes:1) , (_)async {

    if( !busy){
      busy = true;
      await downloader.download();
      busy = false;
    }    
  });

2 个答案:

答案 0 :(得分:2)

要在完成后短暂延迟后重复一个功能,你:

  • 需要知道什么时候完成,
  • 需要知道短暂的延迟何时过去,
  • 并需要再次调用该函数。

我将创建一个单独的函数来执行调用和重新调用,因为它可以更好地分离关注点。 对于第一点,我假设函数在完成后返回Future。然后有很多不同的等待短暂延迟的方法,我将使用最基本的方法Public WriteOnly Shadows Property Enabled() As Boolean Set(ByVal Value As Boolean) cbo1.Enabled = Value cbo2.Enabled = Value End Set End Property ,然后通过再次调用该函数重复该过程。

new Timer

如果想要收回错误,可以创造一个新的未来:

Future myFunction() {
  // do long operation in background, complete returned future when done.
}

void repeatMyFunction() {
  myFunction().then((_) {
    // using .then instead of .whenComplete, so we stop in
    // case of an error.
    new Timer(const Duration(millseconds: shortDelay), repeatMyFunction);
  });
}

如果您允许多个错误,并且不想为一个错误停止,则可以将错误作为流返回,并且,将函数结果作为值添加,以便进行良好测量:

Future repeatMyFunction() {
  Completer completer = new Completer();
  void loop() {
    myFunction().then((_) {
      // using .then instead of .whenComplete, so we stop in
      // case of an error.
      new Timer(const Duration(millseconds: shortDelay), loop);
    }, onError: completer.completeError);
  }
  loop();
  return completer.future;
}

这些重复方法都没有办法再次阻止它。为此,我将额外的未来传递给repeat函数,并在未来完成时停止。

Stream repeatMyFunction() {
  StreamController controller = new StreamController();
  void loop() {
    myFunction().then(controller.add, onError: controller.addError)
                .whenComplete(() {
      new Timer(const Duration(millseconds: shortDelay), loop);
  }
  loop();
  return controller.stream;
}

其他变体也可以获得停止 - 未来,并在停止 - 未来完成时完成未来/关闭流。

Günter的建议也很好,而且更简单(但是细粒度控制更少,这是我喜欢的)。您可以使用以下命令将其代码转换为流:

void repeatMyFunction(Future stop) {
  bool stopFlag = false;
  stop.whenComplete(() { stopFlag = true; });
  void loop() {
    myFunction().then((_) {
      if (!stopFlag) {
        new Timer(const Duration(millseconds: shortDelay), loop);
      }
    });
  }
  loop();
}

答案 1 :(得分:1)

Future myFunction() async {
  await downloader.download();
  await new Future.delayed(const Duration(milliseconds:200),  myFunction);
}

或避免在上面的代码运行太长时会发生堆栈溢出

Future myFunction() async {
  while(true) {
    await downloader.download();
    await new Future.delayed(const Duration(minutes:1), (){});
  }
}