asBroadcastStream 方法

Stream<T> asBroadcastStream(
  1. {void onListen(
    1. StreamSubscription<T> subscription
    )?,
  2. void onCancel(
    1. StreamSubscription<T> subscription
    )?}
)

返回一个多订阅流,产生与当前流相同的事件。

返回的流将在第一个订阅者添加时订阅此流,并且会保持订阅,直到此流结束或回调取消订阅。

如果提供了 onListen,则它将使用表示此流底层订阅的类似于订阅的对象进行调用。在 onListen 调用期间,可以暂停、恢复或取消订阅。不能更改事件处理器,包括使用 StreamSubscription.asFuture

如果提供了 onCancel,则当返回的流停止拥有监听器时,将以类似 onListen 的方式调用它。如果稍后获得新的监听器,则再次调用 onListen 函数。

使用回调,例如,在没有订阅者时暂停底层订阅,以防止丢失事件,或在没有监听器时取消订阅。

取消操作是为了在没有当前订阅者时使用。如果传递给 onListenonCancel 的订阅被取消,那么当前订阅在返回的广播流上永远不会发射任何更多的事件,甚至不包括完成事件。

示例

final stream =
    Stream<int>.periodic(const Duration(seconds: 1), (count) => count)
        .take(10);

final broadcastStream = stream.asBroadcastStream(
  onCancel: (controller) {
    print('Stream paused');
    controller.pause();
  },
  onListen: (controller) async {
    if (controller.isPaused) {
      print('Stream resumed');
      controller.resume();
    }
  },
);

final oddNumberStream = broadcastStream.where((event) => event.isOdd);
final oddNumberListener = oddNumberStream.listen(
      (event) {
    print('Odd: $event');
  },
  onDone: () => print('Done'),
);

final evenNumberStream = broadcastStream.where((event) => event.isEven);
final evenNumberListener = evenNumberStream.listen((event) {
  print('Even: $event');
}, onDone: () => print('Done'));

await Future.delayed(const Duration(milliseconds: 3500)); // 3.5 second
// Outputs:
// Even: 0
// Odd: 1
// Even: 2
oddNumberListener.cancel(); // Nothing printed.
evenNumberListener.cancel(); // "Stream paused"
await Future.delayed(const Duration(seconds: 2));
print(await broadcastStream.first); // "Stream resumed"
// Outputs:
// 3

实现

Stream<T> asBroadcastStream(
    {void onListen(StreamSubscription<T> subscription)?,
    void onCancel(StreamSubscription<T> subscription)?}) {
  return new _AsBroadcastStream<T>(this, onListen, onCancel);
}