You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用Timer及cancel()方法的执行异常问题

问题分析与解决

首先要纠正一个误解:timer.cancel()只会终止Timer的周期性回调,并不会终止后续代码的执行。你看不到This comes afterwards的核心原因是对Dart的异步执行顺序理解有误,再加上可能的日志输出问题。

为什么输出顺序和你预期的不一样?

Dart的代码执行遵循事件循环机制:

  • 同步代码会被优先执行:你创建Timer.periodic的操作是同步的,但Timer的回调函数是异步任务,会被放到事件队列中等待处理。
  • 所以developer.log('This comes afterwards')这行同步代码,会在Timer的任何一次回调触发之前就执行完毕。它的输出应该出现在所有Timer日志的最顶部,而不是你预期的最后。

为什么你没看到这行日志?

大概率是这两种情况:

  • 输出顺序没注意到:它其实已经打印了,只是在日志的最开头,你可能没留意到;
  • developer.log的输出被过滤:developer.log默认受日志级别和系统配置影响,有时候会被控制台过滤。你可以换成print()来测试,它的输出更直接,不容易被过滤。

如果你想在Timer结束后执行代码

如果你的真实需求是在Timer完成(调用cancel后)再执行后续代码,那应该把代码放到Timer的回调函数内部,紧跟在timer.cancel()之后:

var counter = 0;

Timer.periodic(const Duration(milliseconds: 50), (timer) {
  print('Actual counter ' + counter.toString());
  counter++;
 
  if (counter == 5) {
    print('TIMER DONE');
    timer.cancel();
    print('This comes afterwards'); // 这里会在Timer结束后执行
  }
});

如果你只是想看到原代码的日志输出

把developer.log换成print(),同时注意观察输出顺序:

import 'dart:async';

void main() {
  var counter = 0;

  Timer.periodic(const Duration(milliseconds: 50), (timer) {
    print('Actual counter ' + counter.toString());
    counter++;
   
    if (counter == 5) {
       print('TIMER DONE');
        timer.cancel();
    }
  });

  print('This comes afterwards'); // 这行会先打印
}

这段代码的正确输出顺序应该是:

This comes afterwards
Actual counter 0
Actual counter 1
Actual counter 2
Actual counter 3
Actual counter 4
TIMER DONE

内容的提问来源于stack exchange,提问作者Heady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:01:45