阅读 122

Flutter: Stream 实现定时轮询功能

Stream 是 dart 的核心库之一。Future 用于表示单个运算的结果,而 Stream 则表示多个结果的序列。

今天我们来分享一段代码,通过 Stream 来实现定时轮询功能:

typedef Future<T> FutureGenerator<T>();

class StreamTool {

  /// interval 轮询时间间隔
  /// maxCount 最大轮询数
  Stream<T> timedPolling<T>(Duration interval, FutureGenerator<T> future,
      [int maxCount]) {
    StreamController<T> controller;
    int counter = 0;
    bool polling = true;

    void stopTimer() {
      polling = false;
    }

    void tick() async {
      counter++;
      T result = await future();
      if (!controller.isClosed) {
        controller.add(result);
      }
      if (counter == maxCount) {
        stopTimer();
        controller.close();
      } else if (polling) {
        Future.delayed(interval, tick);
      }
    }

    void startTimer() {
      polling = true;
      tick();
    }
    
    //StreamSubscription调用pause,cancel时,stream里面的轮询也能响应暂停或取消
    controller = StreamController<T>(
      onListen: startTimer,
      onPause: stopTimer,
      onResume: startTimer,
      onCancel: stopTimer,
    );

    return controller.stream;
  }
}

使用方式,如下test方法示例:

//配合test,模拟future任务
Future<String> testFuture() async {
    //模拟耗时
    await Future.delayed(Duration(seconds: 1));
    String randomStr = Random().nextInt(10).toString();
    return Future.value(randomStr);
  }

void test() {
    var pollingStream = timedPolling(const Duration(seconds: 1), testFuture, 15);
    StreamSubscription<String> subscription;
    int counter = 0;
    //进行流内容监听
    subscription = pollingStream.listen((result) {
      counter++;
      print("stream result is $result");
      if (counter == 5) {
        // 在第5次打印时,通知subscription暂停,5秒后恢复,暂停期间,stream内的轮询也会暂停
        subscription?.pause(Future.delayed(const Duration(seconds: 5)));
      }
    });
  }
知识点# Stream有两种类型:

第一种: Single-Subscription 类型的 Stream,只能设置一次监听,重复设置会丢失原来的事件。上面的代码实现属于这种类型,好处是我们能在生命周期进行关联方法的调用:

controller = StreamController<T>(
      onListen: startTimer, //监听成立时,开启轮询任务
      onPause: stopTimer, //暂停时,关闭轮询
      onResume: startTimer, //暂停恢复后,重新开始轮询
      onCancel: stopTimer, //取消时,停止轮询
    )

第二种:Broadcast 类型的 Stream,可以在同一时间设置多个不同的监听器同时监听。我们常用这种类型的 Stream 实现广播通知,有兴趣的同学可以看看之前写的文章:Flutter使用Stream进行消息通知
关键代码如下:

StreamController<T>.broadcast().stream

作者:李小轰

原文链接:https://www.jianshu.com/p/ae57192bd4a7

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐