章
目
录
Dart Stream主要分为两种类型,分别是Single-Subscription Stream(单订阅流)和Broadcast Stream(广播流)。这两种类型在功能和适用场景上有着明显的区别,下面我们就来详细探讨一下。
一、Single-Subscription Stream(单订阅流)
(一)单订阅流的特点
单订阅流是Dart中Stream的默认类型。它有一个很关键的特性,就是只能被一个监听器订阅。如果尝试多次订阅,哪怕之前的订阅已经取消,也会抛出异常。这就好比一个特定的消息只能被一个人接收,其他人再想接收就不被允许了。这种特性使得单订阅流特别适合一对一的异步事件处理场景,在这些场景中,事件需要按顺序依次提供,而且不能出现丢失的情况。
(二)适用场景
像网络请求、文件读取等场景就非常适合使用单订阅流。例如在进行网络请求时,我们通常只需要一个监听器来处理请求返回的数据,确保数据按顺序被正确处理。在文件读取时,也希望按顺序读取数据,避免出现混乱。
(三)代码示例
下面通过代码来看看单订阅流的使用:
// 创建一个值为42的单订阅流
Stream<int> myStream = Stream.value(42);
// 通过可迭代对象创建一个单订阅流,包含1到5这几个数字
Stream<int> iterableStream = Stream.fromIterable([1, 2, 3, 4, 5]);
// 使用StreamController创建一个单订阅流
StreamController<int> streamController = StreamController();
Stream<int> dataStream = streamController.stream;
在创建好单订阅流后,我们可以使用listen
方法来监听数据,还可以设置错误回调和完成回调:
dataStream.listen(
(data) => print("Received: $data"), // 数据回调,用于处理接收到的数据
onError: (error) => print("Error: $error"), // 错误回调(可选),当流发生错误时会调用
onDone: () => print("Stream completed") // 完成回调(可选),当流结束时会调用
);
二、Broadcast Stream(广播流)
(一)广播流的特性
与单订阅流不同,广播流允许多个监听器同时订阅。这意味着一个事件可以同时被多个监听器接收,就像广播一样,能让很多人同时听到消息。即使在没有监听者的时候,事件也会被正常发送。不过,广播流也有它的局限性,它不能保留已发送的事件,新的订阅者无法收到之前已经发送过的事件。
(二)适用场景
广播流适用于一对多的事件广播场景。比如在用户登录状态变化的场景中,可能有多个组件需要同时知道用户的登录状态,这时就可以使用广播流来广播登录状态的变化。在传感器数据监听的场景中,也可以使用广播流,多个不同的功能模块都能同时监听传感器数据。
(三)创建方式及代码示例
- 将单订阅流转换为广播流:可以利用
asBroadcastStream
方法将单订阅Stream转换为广播Stream。示例代码如下:
// 创建一个按秒生成递增数字的单订阅流
Stream<int> singleStream = Stream.periodic(const Duration(seconds: 1), (count) => count);
// 将单订阅流转换为广播流
Stream<int> broadcastStream = singleStream.asBroadcastStream();
- 直接创建广播流:还可以使用
StreamController.broadcast
直接创建广播Stream:
// 使用StreamController.broadcast直接创建一个广播流
StreamController<int> controller = StreamController.broadcast();
Stream<int> broadcastStream = controller.stream;
创建好广播流后,我们可以添加多个监听器:
broadcastStream.listen(
(data) => print("Listener 1: $data"),
);
broadcastStream.listen(
(data) => print("Listener 2: $data"),
);
在这段代码中,两个不同的监听器都能接收到广播流发送的数据。
通过以上介绍,相信大家对Dart中Stream的两种类型——Single-Subscription Stream和Broadcast Stream有了更清晰的认识。在实际编程中,我们可以根据具体的需求,选择合适的Stream类型来处理异步数据,赶紧去试试吧。