Stream、StreamBuilder和StreamController的学习

Stream和StreamBuilder

PS:Future和Sream的一些区别
  • Future在snapshot的ConnectionState为done的时候返回结果;Stream在active的时候返回结果
  • Future只返回一次结果,Stream可以返回多次(一直返回)

Stream

手动创建stream

//使用async*和yield关键字创建stream
Stream<int> getDateTime() async* {
    while(true){
        await Futrue.delay(Duration(secends:1));
        yield DateTime.now();   //每隔1秒这个数据流返回一次当前的时间
    }
    
}
//每隔一秒sream返回42的值
Stream.periodic(Duration(seconds:1),(_)=>42);
//对流里面的数据进行操作
Stream.map((event)=>event*20);
//对流里面的数据进行一些判断
Stream.where((event)=>event is int);
//对流里面的数据进行去重
Stream.distinct();
//将一个stream转换为另外一个stream
Stream.transform

复制代码

一般情况下,stream只能有一个监听,如果需要进行多处监听,使用:

StreamController.broadcast();
复制代码

使用广播的方式(StreamController.brocast())不会进行缓存;
而非广播的方式能进行缓存。
验证:

fianl controller = StreamController();
controller.sink.add(10);
Future.delay(Duraton(seconds:5),(){
    controlelr.stream.listen(event){
        print('event:$event');  //五秒后打印出5
    };
});
fianl broadcastController = StreamController.broadcast();
controller.sink.add(20);
Future.delay(Duraton(seconds:5),(){
    broadcastController.stream.listen(event){
        //没有任何输出,只有在5秒后往stream添加数据才会被监听到
        print('event:$event');  
    };
});
复制代码

SreamBuilder

StreamBuilder也是监听Stream的一种方式
在StreamBuilder的builder方法中,能够获取数据快照snapshot。

snapshot.connectionState:

  • none:Stream==null时
  • waiting:监听的数据流中还没有内容时
  • active:监听的数据流有数据的时候
  • done:监听的数据流结束时会调用
class _StreamBuilderPageState extends State<StreamBuilderPage> {
  StreamController _controller = StreamController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    //3秒后往Stream中添加10这个数据
    Future.delayed(Duration(seconds: 3), () => _controller.sink.add(10));
    //10秒后关闭这个数据流的sink
    Future.delayed(Duration(seconds: 10), () => _controller.sink.close());
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _controller.close();
  }

///页面中先是先是Waiting
///当StreamBuilder监听到stream添加了10后显示Action:10
///10秒后,因为调用了sink.close,所以显示Done
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: DefaultTextStyle(
        style: TextStyle(fontSize: 20, color: Colors.black),
        child: Center(
          child: StreamBuilder(
              stream: _controller.stream,
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.waiting:
                    return Text('Waiting');
                  case ConnectionState.active:
                    if (snapshot.hasData) {
                      return Text('Active:${snapshot.data}');
                    }
                    return Container();
                  case ConnectionState.done:
                    return Text('Done');
                }
                return Container();
              }),
        ),
      ),
    );
  }
}
复制代码

SreamController

fianl controller = StreamController();
StreamController.sink.add();    //给stream添加数据
StreamController.sink.addError();    //给stream添加错误
StreamController.steam.listen((event){
    
},onError(err){
    
},onDone(){
    
}); //给stream添加监听事件
StreamController.close();   //关闭stream

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享