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
相关推荐
WDeLiang5 小时前
Flutter - UIKit开发相关指南 - 导航
flutter·ios·dart
程序猿阿伟10 小时前
《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
前端·flutter
融云19 小时前
集成指南:如何采用融云 Flutter IMKit 实现双端丝滑社交体验
flutter
EndingCoder1 天前
跨平台移动开发框架React Native和Flutter性能对比
flutter·react native·react.js
Double Point1 天前
`RotationTransition` 是 Flutter 中的一个动画组件,用于实现旋转动画效果
flutter
亚洲小炫风1 天前
flutter 项目工程文件夹组织结构
flutter·flutter工程结构
Double Point1 天前
Flutter 中 vsync
flutter
Double Point1 天前
ScaleTransition 是 Flutter 中的一个动画组件,用于实现缩放动画效果。
flutter
saxihuangxing1 天前
flutter build apk出现的一些奇怪的编译错误
flutter
恋猫de小郭2 天前
Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
android·flutter·ios