🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 参考资料 [Flutter完整开发实战详解(十一、全面深入理解Stream)](https://juejin.im/post/5cc2acf86fb9a0321f042041) [异步UI更新(FutureBuilder、StreamBuilder)](https://book.flutterchina.club/chapter7/futurebuilder_and_streambuilder.html) ## Dart中的Stream `Stream`就是事件流或者管道,事件流相信大家并不陌生,简单的说就是:**基于事件流驱动设计代码,然后监听订阅事件,并针对事件变换处理响应**。 在 Flutter 中,整个`Stream`设计外部暴露的对象主要如下图,主要包含了`StreamController`、`Sink`、`Stream`、`StreamSubscription`四个对象。 ![](https://img.kancloud.cn/5c/a7/5ca7af90859fb81ec04391fe48f6dbce_1240x635.png) ~~~ class DataBloc{ ///控制器 StreamController<List<String>> _dataController = StreamController<List<String>>(); ///事件的入口 StreamSink<List<String>> get _dataSink => _dataController.sink; ///获取 Stream 用于监听 Stream<List<String>> get _dataStream => _dataController.stream; ///事件订阅对象 StreamSubscription _dataSubscription; init(){ ///监听事件 _dataSubscription = _dataStream.listen((value){ print(value); }); _dataSink.add(["first", "second", "three", "more"]); } close() { ///关闭 _dataSubscription.cancel(); _dataController.close(); } } ~~~ 个人理解: StreamController:一个大管家 StreamSink:用于发送事件 Stream\StreamSubscription:用于监听,StreamSubscription是Stream产生的 ## Flutter中的Stream 在 Flutter 中通过`StreamBuilder``StreamBuilder`配合`Stream`来展示流上事件(数据)变化的UI组件。下面看一下`StreamBuilder`的默认构造函数: ~~~ StreamBuilder({ Key key, this.initialData, Stream<T> stream, @required this.builder, }) ~~~ * `stream`:`StreamBuilder`依赖的`stream` * `initialData`:初始数据,用户设置默认数据。 * `builder`:Widget构建器;该构建器会在`Future`执行的不同阶段被多次调用,构建器签名如下: ~~~ Function (BuildContext context, AsyncSnapshot snapshot) ~~~ `snapshot`会包含当前异步任务的状态信息及结果信息 ,比如我们可以通过`snapshot.connectionState`获取异步任务的状态信息、通过`snapshot.hasError`判断异步任务是否有错误等等,完整的定义读者可以查看`AsyncSnapshot`类定义。 另外,`FutureBuilder`的`builder`函数签名和`StreamBuilder`的`builder`是相同的。 例子: ~~~ Widget buildStreanBuilder() { return StreamBuilder<List<String>>( stream: _dataStream, initialData: ["none"], ///这里的 snapshot 是数据快照的意思 builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) { ///获取到数据,为所欲为的更新 UI var data = snapshot.data; return new Text(data.toString()); }); } ~~~