第二百四十七回 如何实现每隔一段时间执行某项目任务

本文介绍了如何在Flutter中使用Stream.periodic实现每隔一段时间执行任务,包括原理分析、具体实现方法(如StreamBuilder配合)、示例代码以及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


我们在上一章回中介绍了"再谈showMenu的用法",本章回中将介绍 如何实现每隔一段时间执行某项任务.闲话休提,让我们一起Talk Flutter吧。

在这里插入图片描述

1. 概念介绍

在实际项目中会有定时执行任务的需求,比如每隔1秒去发送网络心跳包,对于这样的需求,可以通过Stream.periodic(Duration,(){}).take(times)来实现,再配合StreamProvider或者StreamBuilder就可以监听Stream中的事件。本章回中将介绍详细的使用方法。

2. 方法与原理

2.1 实现方法

介绍完概念后,我们看看如何实现这个概念,下面是具体的实现方法:

  • 创建一个Stream,并且调用它的priodic方法来执行定期任务;
  • 创建一个StreamBuilder,用来监听Stream中的事件;
  • 通过StreamBuilder中的buidler属性获取Stream中的事件;
  • 获取事件后,可以依据事件中的数据实现相关的逻辑业务处理;

2.2 实现原理

上面的实现方法中使用StreamBuilder来监听Stream中的事件,这个容易理解,我们重点看看Stream是如何实现每隔一段时间执行某项任务的,下面是它的源代码:

 factory Stream.periodic(Duration period,
      [T computation(int computationCount)?]) {
    if (computation == null && !typeAcceptsNull<T>()) {
      throw ArgumentError.value(null, "computation",
          "Must not be omitted when the event type is non-nullable");
    }
    var controller = _SyncStreamController<T>(null, null, null, null);
    // Counts the time that the Stream was running (and not paused).
    Stopwatch watch = new Stopwatch();
    controller.onListen = () {
      int computationCount = 0;
      void sendEvent(_) {
        watch.reset();
        if (computation != null) {
          T event;
          try {
            event = computation(computationCount++);
          } catch (e, s) {
            controller.addError(e, s);
            return;
          }
          controller.add(event);
        } else {
          controller.add(null as T); // We have checked that null is T.
        }
      }

      Timer timer = Timer.periodic(period, sendEvent);
      controller
        ..onCancel = () {
          timer.cancel();
          return Future._nullFuture;
        }
        ..onPause = () {
          watch.stop();
          timer.cancel();
        }
        ..onResume = () {
          Duration elapsed = watch.elapsed;
          watch.start();
          timer = new Timer(period - elapsed, () {
            timer = Timer.periodic(period, sendEvent);
            sendEvent(null);
          });
        };
    };
    return controller.stream;
  }

从上面的源代码中可以看到,该代码主要通过Timer来实现定期执行某项任务,不过它也有一些局限性,因为event的值递增的(computation(computationCount++))

如果使用StreamProvider指定初始值,但是它还会回到原来的默认值,比如指定泛型为int,初始值为3,它开始运行时值为3,指定时间到了后又变成了默认值0.此后这个值进行递增,直到执行times次后停止。

3. 示例代码

///每隔1s运行一次,一共运行3次
  final Stream<int> _stream2 = Stream.periodic(const Duration(seconds: 1,),(count) => (count+1)).take(3);

  StreamBuilder<int>(
    stream: _stream2,
    builder: (context,data){
      var str = data.data == null? 'no value' : data.data.toString();
      return Text("value of Stream: $str");
    },
  ),

上面的示例完全按照实现方法中的步骤来编写,代码中实现了一个定期任务:第隔1秒运行一次,一共运行3次。

4. 内容总结

最后,我们对本章回的内容做一个全面的总结:

  • 通过Stream的periodic方法可以实现定期任务;
  • Stream中的periodic方法本质上是通过Timer实现的;
  • Stream中的periodic方法只能递增,具有一定的局限性;

看官们,与"如何实现每隔一段时间执行某项目任务"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值