Flutter Stream 简单使用

130 阅读2分钟

Stream 是什么

异步数据事件的源, 抽象类,用于表示一序列异步数据的源。它是一种产生连续事件的方式,可以生成数据事件或者错误事件,以及流结束时的完成事件。

Stream 分类

流可以分为两类:

  • 单订阅流(Single Subscription),这种流最多只能有一个监听器(listener)

  • 多订阅流(Broadcast),这种流可以有多个监听器监听(listener)

单订阅流在发送完成事件之前只允许设置一个监听器,并且只有在流上设置监听器后才开始产生事件,取消监听器后将停止发送事件。即使取消了第一个监听器,也不允许在单订阅流上设置其他的监听器。

广播流则允许设置多个监听器,也可以在取消上一个监听器后再次添加新的监听器。

Stream 有同步流和异步流之分。

它们的区别在于同步流会在执行 addaddError 或 close 方法时立即向流的监听器 StreamSubscription 发送事件,而异步流总是在事件队列中的代码执行完成后在发送事件。

Stream 相关对象

StreamController带有控制流方法的流。 可以向它的流发送数据,错误和完成事件,也可以检查数据流是否已暂停,是否有监听器。sync 参数决定这个流是同步流还是异步流。

StreamController _streamController = StreamController(
  onCancel: () {},
  onListen: () {},
  onPause: () {},
  onResume: () {},
  sync: false,
);

StreamSink流事件的入口。提供 addaddErroraddStream 方法向流发送事件

abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
  Future close();
  /// ...
  Future get done;
}

StreamSubscription流的监听器。提供 cacenlpauseresume 等方法管理


abstract class StreamSubscription<T> {
  /// ...
}

StreamSubscription subscription = StreamController().stream.listen(print);
subscription.onDone(() => print('done'));

StreamBuilder使用流数据渲染 UI 界面的部件

StreamBuilder(
  // 数据流
  stream: stream,
  // 初始数据
  initialData: 'loading...',
  builder: (context, AsyncSnapshot snapshot) {
    // AsyncSnapshot 对象为数据快照,缓存了当前数据和状态
    // snapshot.connectionState
    // snapshot.data
    if (snapshot.hasData) {
      Map data = snapshot.data;
      return Text(data),
    }
    return CircularProgressIndicator();
  },
)

Stream 创建

  1. 从现有的生成一个新的流 Stream,使用 mapwheretakeWhile 等方法
// 整数流
Stream<int> intStream = StreamController<int>().stream;
// 偶数流
Stream<int> evenStream = intStream.where((int n) => n.isEven);
// 两倍流
Stream<int> doubleStream = intStream.map((int n) => n * 2);
// 数字大于 10 的流
Stream<int> biggerStream = intStream.takeWhile((int n) => n > 10);    
  1. Future 对象生成
Future<int> _delay(int seconds) async {
  await Future.delayed(Duration(seconds: seconds));
  return seconds;
}

List<Future> futures = [];
for (int i = 0; i < 10; i++) {
  futures.add(_delay(3));
}

Stream _futuresStream = Stream.fromFutures(futures);

Stream 使用

//创建StreamController
StreamController streamCtrl = StreamController.broadcast();

//用做添加事件的入口
StreamSink get sink => streamCtrl.sink;

//Stream用来监听数据
Stream get stream => streamCtrl.stream;

//Stream的订阅对象
StreamSubscription? subscription1;
StreamSubscription? subscription2;


@override
void initState() {
  super.initState();

  //监听数据
  subscription1 = stream.listen((event) {
    print('第一个订阅');
    print(event);
  });
  subscription2 = stream.listen((event) {
    print('第二个订阅');
    print(event);
  });
}

@override
void dispose() {
  super.dispose();
  //取消订阅
  subscription1?.cancel();
  subscription2?.cancel();
  //关闭流
  streamCtrl.close();
}

添加流数据

sink.add('abc');

或

streamCtrl.add('abcd');