Flutter 三点三:Dart Stream

Stream

  • Stream用于接收异步事件
  • Stream 可以接收多个异步事件
  • Stream.listen()方法返回StreamSubscription 可用于取消事件订阅,取消后,不再接收事件

基本使用

复制代码
 Stream.fromFutures([
       Future.delayed(Duration(seconds: 1),(){
           return "事件1";
       }),

       Future.delayed(Duration(seconds: 3),(){
           return "事件2";
       }),
       Future.delayed(Duration(seconds: 5),(){
           return "事件3";
       })
   ]).listen((event) {
       print("${DateTime.now().millisecondsSinceEpoch} >> "+event);
   }).onDone(() {
       print("${DateTime.now().millisecondsSinceEpoch} >> onDone");
   });


Stream.fromFutures([
       Future.delayed(Duration(seconds: 1),(){
           return "事件1";
       }),

       Future.delayed(Duration(seconds: 3),(){
           return "事件2";
       }),
       Future.delayed(Duration(seconds: 5),(){
           return "事件3";
       })
   ]).listen((event) {print("${DateTime.now().millisecondsSinceEpoch} >> "+event);},onError: (error){},onDone: (){});

运行结果

复制代码
1703817812594 >> 事件1
1703817814583 >> 事件2   //2s后打印
1703817816574 >> 事件3   //2s后打印
1703817816578 >> onDone

另外一种使用方式 更加灵活

复制代码
var streamController =  StreamController();
    streamController.stream.listen((event) {print(event);});
    streamController.add("事件1");
    streamController.add("事件2");
    streamController.add("事件3");

运行结果

复制代码
事件1
事件2
事件3

由结果可以看出,Stream类似于rxjava

Stream.listen()方法返回StreamSubscription 可用于取消事件订阅,取消后,不再接收事件

未取消订阅

复制代码
 StreamController streamController =  StreamController();
    StreamSubscription streamSubscription = streamController.stream
        .listen((event) {
            print(event);
        });
    streamController.add("事件1");
    streamController.add("事件2");
    Future((){
        sleep(Duration(seconds: 2));
        // streamSubscription.cancel();
        streamController.add("事件3");
    });

结果

复制代码
事件1
事件2
事件3

取消订阅后

复制代码
 StreamController streamController =  StreamController();
    StreamSubscription streamSubscription = streamController.stream
        .listen((event) {
            print(event);
        });
    streamController.add("事件1");
    streamController.add("事件2");
    Future((){
        sleep(Duration(seconds: 2));
        streamSubscription.cancel();
        streamController.add("事件3");
    });

结果

复制代码
事件1
事件2
StreamController

构造函数参数表示stream的生命周期

复制代码
/**
onListen: 监听开始开始
onPause:监听暂停
onResume:监听重启
onCancel:监听取消
sync :同步 or 异步
*/
 factory StreamController(
      {void onListen()?,
      void onPause()?,
      void onResume()?,
      FutureOr<void> onCancel()?,
      bool sync = false}) {
    return sync
        ? _SyncStreamController<T>(onListen, onPause, onResume, onCancel)
        : _AsyncStreamController<T>(onListen, onPause, onResume, onCancel);
  }

StreamController streamController =  StreamController(
        onListen: (){
           print("onListen");
        },
        onPause: (){
            print("onPause");
        },
        onResume: (){
            print("onResume");
        },
        onCancel: (){
            print("onCancel");
        },
    );
    StreamSubscription streamSubscription = streamController.stream
        .listen((event) {
            print(event);
        });
    streamController.add("事件1");
    streamSubscription.pause();
    streamSubscription.resume();
    streamController.add("事件2");
    Future((){
        sleep(Duration(seconds: 2));
        streamSubscription.cancel();
        streamController.add("事件3");
    });

运行结果:

复制代码
onListen
onPause
事件1
事件2
onResume
onCancel

Stream其他构造方法

复制代码
void main() async{

   Stream.value(1)
       .listen((event) {print(event);});
   
   Stream.fromIterable([2,3,4,5])
        .listen((event) {print(event);});

   //结合await使用
   Stream stream = Stream.fromIterable([6,7,8,9]);
   await for(var i in stream){
       print(i);
   }
}

运行结果:

复制代码
1
2
6
3
7
4
8
5
9

Stream.periodic 每隔多长时间执行一次任务

复制代码
 Stream.periodic(Duration(seconds: 2),(computationCount){
        return "它死啦,它火啦,它死啦才火啦!${computationCount}";
    })
    .take(5)  //执行5次 不设置一直执行
    .listen((event) {print(event);});

运行结果

复制代码
它死啦,它火啦,它死啦才火啦!0
它死啦,它火啦,它死啦才火啦!1
它死啦,它火啦,它死啦才火啦!2
它死啦,它火啦,它死啦才火啦!3
它死啦,它火啦,它死啦才火啦!4

async* 标记的方法称为异步生成器,yield生成单个元素,yield*生成多个元素,最终汇集成流

复制代码
void main(){
    createStream()
        .listen((event) {print("${DateTime.now().millisecondsSinceEpoch} >> ${event}");});
}

Stream<int> createStream() async*{
    for(int i=0;i<10;i++){
        sleep(Duration(seconds: 1));  //1s钟生成一个
        yield i;
    }
}

//结果

复制代码
1703821955894 >> 0
1703821956912 >> 1
1703821957921 >> 2
1703821958929 >> 3
1703821959940 >> 4
1703821960953 >> 5
1703821961960 >> 6
1703821962971 >> 7
1703821963982 >> 8
1703821964993 >> 9
相关推荐
恋猫de小郭1 小时前
Flutter Riverpod 3.0 发布,大规模重构下的全新状态管理框架
android·前端·flutter
RaidenLiu3 小时前
Riverpod 3:重建控制的实践与性能优化指南
前端·flutter
蒋星熠19 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
卢叁1 天前
Flutter之自定义TabIndicator
前端·flutter
萧雾宇1 天前
Android Compose打造仿现实逼真的烟花特效
android·flutter·kotlin
拜无忧1 天前
【教程】flutter常用知识点总结-针对小白
android·flutter·android studio
拜无忧1 天前
【教程】Flutter 高性能项目架构创建指南:从入门到高性能架构
android·flutter·android studio
醉过才知酒浓1 天前
flutter 拦截返回按钮的方法(WillPopScope or PopScope)
flutter
傅里叶1 天前
sudo启动Flutter程序AMD初始化失败
linux·flutter
苦逼的搬砖工1 天前
Flutter UI Components:闲来无事,设计整理了这几年来使用的UI组件库
前端·flutter