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

Flutter中Timer.periodic触发15分钟定时函数失效问题排查

问题分析与修复方案

核心问题

你的触发逻辑if ((timesupSeconds % (15 * 60)) == 0)有两个关键缺陷:

  1. Timer执行精度偏差:Timer.periodic的1秒间隔不是绝对精准的,系统调度延迟可能让回调在整秒之后才执行(比如第900秒的100ms处),这时timesupSeconds已经变成901,直接错过等于0的瞬间。
  2. 无去重机制:即使刚好命中整秒,每秒执行的Timer可能在同一秒内重复触发逻辑,同时错过触发点的概率极高。

修复代码示例

方案1:基于周期区间判断(兼容原有逻辑)

void clock() {
  int? lastTriggeredSecond; // 记录上一次触发的秒数,防止重复执行
  Timer.periodic(const Duration(seconds: 1), (clock) {
    var timesUp = DateTime.now().millisecondsSinceEpoch;
    var timesupSeconds = (timesUp / 1000).floor();
    final fifteenMinutes = 15 * 60;
    
    // 计算当前在15分钟周期内的剩余秒数
    final cycleSeconds = timesupSeconds % fifteenMinutes;
    var minutes = (cycleSeconds / 60).floor();
    var seconds = cycleSeconds % 60;

    // 仅当刚进入新的15分钟周期且未触发过时执行逻辑
    if (cycleSeconds == 0 && lastTriggeredSecond != timesupSeconds) {
      print('it is 15 minutes');
      lastTriggeredSecond = timesupSeconds;
    }

    setState(() {
      time = '$minutes m: $seconds';
    });
  });
}

方案2:一次性Timer精准触发(更可靠)

直接计算距离下一个15分钟节点的时间,到点后执行逻辑并重新调度,完全规避周期Timer的精度问题:

void startClock() {
  // 初始化计时显示
  updateTimerDisplay();
  // 调度第一次15分钟触发
  scheduleNext15MinuteTrigger();
}

void updateTimerDisplay() {
  var timesUp = DateTime.now().millisecondsSinceEpoch;
  var timesupSeconds = (timesUp / 1000).floor();
  final fifteenMinutes = 15 * 60;
  final cycleSeconds = timesupSeconds % fifteenMinutes;
  var minutes = (cycleSeconds / 60).floor();
  var seconds = cycleSeconds % 60;

  setState(() {
    time = '$minutes m: $seconds';
  });
  
  // 每秒更新一次计时
  Timer(const Duration(seconds: 1), updateTimerDisplay);
}

void scheduleNext15MinuteTrigger() {
  var now = DateTime.now();
  // 计算下一个15分钟整的时间点(比如当前是12:07,下一个是12:15)
  var nextTrigger = DateTime(now.year, now.month, now.day, now.hour, (now.minute ~/ 15 + 1) * 15, 0);
  var timeToTrigger = nextTrigger.difference(now);
  
  Timer(timeToTrigger, () {
    print('it is 15 minutes');
    // 触发后继续调度下一次
    scheduleNext15MinuteTrigger();
  });
}

额外说明

  • 方案1适合保留原有周期Timer的逻辑,通过区间判断和去重解决触发失效问题;
  • 方案2的精准度更高,分开了计时显示和触发逻辑,代码结构更清晰,适合对触发时间要求严格的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:05:02