dart 如何使Timer.periodic在达到某个条件时自动取消?

pkmbmrz7  于 2023-02-01  发布在  其他
关注(0)|答案(5)|浏览(157)

Timer.periodic()非常适合重复执行某个函数,但是如果在定时器正在执行的函数之外达到任意条件,是否可以让定时器自行取消?

zyfwsgd6

zyfwsgd61#

将计时器传递给回调函数,只需调用cancel()即可:

Timer.periodic(const Duration(seconds: 1), (timer) {
  if(condition) {
    timer.cancel();
  }
});

Timer timer;

startTimer() {
  timer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if(condition) {
      cancelTimer();
    }
  });
}

cancelTimer() {
  timer.cancel();
}

这样,定时器可以独立于定时器事件而被取消。

完整的不可空Dart示例

import 'dart:async';

Timer? timer;
bool condition = false;

void main() async {
  startTimer();

  await Future.delayed(const Duration(milliseconds: 600), () => condition = true);
}

startTimer() {
  timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
    print("condition: ${condition}");
    if (condition) {
      cancelTimer();
    }
  });
}

cancelTimer() {
  timer?.cancel();
  timer = null;
}
ibrsph3r

ibrsph3r2#

您可以将Stream.periodictakeWhile一起使用

bool condition = true;

  Future.delayed(const Duration(seconds: 5), () => condition = false);

  Stream.periodic(const Duration(seconds: 1))
      .takeWhile((_) => condition)
      .forEach((e) {
    print('event: $e');
  });
62o28rlo

62o28rlo3#

我发现的一个解决方案是向返回bool的定时器传递一个函数,然后在满足timer.cancel()时使用它。

periodically(int milliseconds, Function repeat, [Function cancel]) {
  return Timer.periodic(
    Duration(milliseconds: milliseconds),
    (Timer t) {
      repeat();
      if (cancel != null) {
        cancel() ? t.cancel() : null;
      }
    }
  );
}
2w3kk1z5

2w3kk1z54#

我希望上面的解决方案对你来说能很好地工作,但如果不能,那么你也可以尝试下面的代码,因为在我的情况下,上面的解决方案不能很好地工作。

static Timer timerObjVar;
 static Timer timerObj;

   timerObj = Timer.periodic(Duration(seconds: 10), (Timer timer) async {
      timerObjVar = timer;
      _initData();  
   });
    
 // when you want to cancel the timer call this function
  cancelTimer() {

      if (timerObjVar != null) {            
        timerObjVar.cancel();
        timerObjVar = null;
      }

      if (timerObj != null) {           
        timerObj.cancel();
        timerObj = null;
      }
  }
tkclm6bt

tkclm6bt5#

// just using this code, with timer with stop if condition is reached
await Timer.periodic(Duration(milliseconds: 10), (timer) {
     pos += 10;
     if (pos > limit) {
       timer.cancel();
     }
     setState(() {});
   });
 }

相关问题