Flutter中Stream的两种订阅模式?

发布于 1周前 作者 phonegap100 来自 Flutter

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

1 回复

更多关于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 提供了灵活的异步数据处理机制,可以根据实际需求选择适合的订阅模式。

回到顶部