Flutter学习笔记-异步Stream

本文详细介绍了Flutter中的Stream,包括Stream的概念、类型、创建方法及其在UI更新中的应用。讲解了如何使用单订阅流和广播流,以及如何监听网络状态、创建数据流和使用async*函数。示例代码展示了如何利用StreamBuilder响应流数据变化更新UI。
摘要由CSDN通过智能技术生成

在 Flutter 中有两种处理异步操作的方式 FutureStreamFuture 用于处理单个异步操作,Stream 用来处理连续的异步操作。

通俗来说,Stream 就是事件流或者管道:基于事件流驱动设计代码,然后监听订阅事件,并针对事件变换处理响应

在iOS端,Stream类似于RxSwift或者ReactiveCocoa框架的编程思想,通过可观察的流实现异步编程,既然有可观察,就存在消息发送消息订阅

Stream 详解

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

abstract class Stream<T> {
  Stream();
}

Stream 分单订阅流和广播流。

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

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

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

它们的区别在于

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

Stream 家族

  • StreamController:

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

abstract class StreamController<T> implements StreamSink<T> {
  Stream<T> get stream;
  /// ...
}

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:
    流的监听器。提供 cacenl、pause, resume 等方法管理。
abstract class StreamSubscription<T> {
  /// ...
}

StreamSubscription subscription = StreamController().stream.listen(print);
subscription.onDone(() => print('done'));
  • StreamBuilder:
    使用流数据渲染 UI 界面的部件,使用StreamBuilder后,UI界面的更新就不再需要使用setState方法了。
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

在 Dart 有几种方式创建 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);

  • 2、使用 async* 函数。
Stream<int> countStream(int to) async* {
  for (int i = 1; i <= to; i++) {
    yield i;
  }
}

Stream stream = countStream(10);
stream.listen(print);

该段代码的执行过程:
当运行countStream的时候,会立即返回Stream,但函数体并不会执行,一旦开始listen监听数据流,函数体会开始执行。当执行到yield关键字的时候,会将yield声明的求值表达式的计算结果添加到Stream数据流中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值