Flutter中Stream的两种订阅模式?
Flutter中Stream的两种订阅模式?
在 Dart 中,Stream 提供了两种订阅模式,分别是单订阅(Single Subscription)和广播(Broadcast)订阅。这两种模式在使用场景和特性上有所不同。
1. 单订阅模式(Single Subscription Stream)
单订阅流(默认)是指同一时刻只能有一个监听器的流,这意味着只能被订阅一次。适用于处理一次性数据流,或者在生命周期内只会有一个订阅者的情况,比如从文件读取数据、网络请求返回的数据流等。
特性
- 只能订阅一次:一旦有一个监听器监听该流,再尝试监听会导致错误。
- 按顺序接收事件:每个事件会按顺序被处理,数据流不会分发给多个订阅者。
典型应用场景
- 读取文件
- HTTP 响应
- 用户输入等不需要多个订阅的场景
示例
import 'dart:async';
void main() {
// 创建一个单订阅流
Stream<int> singleSubscriptionStream = Stream.fromIterable([1, 2, 3]);
// 订阅流
singleSubscriptionStream.listen((event) {
print("Received event: $event");
});
// 再次订阅会导致错误(如果取消注释以下代码)
// singleSubscriptionStream.listen((event) {
// print("Received event again: $event");
// });
}
2. 广播模式(Broadcast Stream)
广播流是指支持多个监听器的流。广播流允许多个订阅者同时监听,同一个事件会被分发给所有订阅者。适用于数据需要同时被多个监听者使用的情况,比如用户点击事件流、WebSocket 数据流等。
特性
- 支持多个订阅:允许在同一时间内有多个监听器。
- 即使没有订阅者也会持续发送数据:广播流不会等待监听器的注册。
典型应用场景
- 事件总线(Event Bus)
- WebSocket 数据流
- 全局共享的流等
示例
import 'dart:async';
void main() {
// 创建一个广播流
StreamController<int> broadcastController = StreamController.broadcast();
Stream<int> broadcastStream = broadcastController.stream;
// 订阅流
broadcastStream.listen((event) {
print("Listener 1: Received event: $event");
});
// 再次订阅同一个流
broadcastStream.listen((event) {
print("Listener 2: Received event: $event");
});
// 添加事件到流中
broadcastController.add(1);
broadcastController.add(2);
broadcastController.close(); // 关闭流
}
如何创建广播流
将单订阅流转换为广播流非常简单,调用 asBroadcastStream()
即可将单订阅流转为广播流。这样同一流就可以被多个监听器订阅了。
import 'dart:async';
void main() {
// 创建一个单订阅流
Stream<int> singleSubscriptionStream = Stream.fromIterable([1, 2, 3]);
// 转换为广播流
Stream<int> broadcastStream = singleSubscriptionStream.asBroadcastStream();
// 订阅流
broadcastStream.listen((event) {
print("Listener 1: Received event: $event");
});
// 再次订阅同一个流
broadcastStream.listen((event) {
print("Listener 2: Received event: $event");
});
}
总结
- 单订阅流:只允许一个订阅者,适用于一次性数据流的情况。
- 广播流:支持多个订阅者,可以同时将数据分发给多个监听器。
更多关于Flutter中Stream的两种订阅模式?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter中Stream的两种订阅模式?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,Stream
是一种用于处理异步数据流的重要机制,它允许你在数据变化时自动通知监听者。Stream
的两种主要订阅模式是 单订阅(single subscription) 和 广播订阅(broadcast subscription)。下面将展示这两种订阅模式的代码实现。
单订阅模式(Single Subscription)
单订阅模式意味着每个 Stream
只能有一个监听者(StreamSubscription
),一旦有新的数据产生,就会通知这个监听者。如果尝试添加第二个监听者,将会抛出异常。
示例代码:
import 'dart:async';
void main() async {
// 创建一个单订阅模式的 Stream
StreamController<int> controller = StreamController<int>.broadcast(sync: true);
// 注意:上面使用了 .broadcast() 构造函数,但这里我们将其视为单订阅模式,即不添加多个监听者
Stream<int> stream = controller.stream;
// 订阅 Stream
StreamSubscription<int> subscription = stream.listen((value) {
print("Received: $value");
});
// 添加数据到 Stream
controller.add(1);
controller.add(2);
controller.close(); // 关闭 Stream
// 如果尝试添加第二个监听者,将会报错(这里不演示)
// StreamSubscription<int> subscription2 = stream.listen((value) => print("Another listener: $value"));
}
注意:上面的代码虽然使用了 StreamController.broadcast()
构造函数,但这里我们模拟单订阅模式,即只添加一个监听者。如果尝试添加第二个监听者,将会抛出异常。
广播订阅模式(Broadcast Subscription)
广播订阅模式允许多个监听者同时订阅同一个 Stream
,当数据变化时,所有监听者都会收到通知。
示例代码:
import 'dart:async';
void main() async {
// 创建一个广播模式的 Stream
StreamController<int> controller = StreamController<int>.broadcast(sync: true);
Stream<int> stream = controller.stream;
// 第一个监听者
StreamSubscription<int> subscription1 = stream.listen((value) {
print("Listener 1: Received $value");
});
// 第二个监听者
StreamSubscription<int> subscription2 = stream.listen((value) {
print("Listener 2: Received $value");
});
// 添加数据到 Stream
controller.add(1);
controller.add(2);
// 可以在任何时候取消订阅
await Future.delayed(Duration(seconds: 1));
subscription1.cancel();
subscription2.cancel();
// 继续添加数据(虽然监听者已取消,但不会报错)
controller.add(3);
controller.close(); // 关闭 Stream
}
在这个例子中,我们创建了一个广播模式的 Stream
,并添加了两个监听者。当数据添加到 Stream
时,两个监听者都会收到通知。此外,我们展示了如何取消订阅,即使 Stream
在监听者取消后继续添加数据,也不会报错。
总结
- 单订阅模式:每个
Stream
只能有一个监听者,适用于需要独占数据流的场景。 - 广播订阅模式:允许多个监听者同时订阅同一个
Stream
,适用于需要共享数据流的场景。
通过这两种模式,Flutter 提供了灵活的异步数据处理机制,可以根据实际需求选择适合的订阅模式。