有人订阅时做什么?

时间:2019-01-28 13:40:05

标签: asynchronous dart stream

我有一个BLE设备的数据流的广播流。

为了从该流中获取数据,我需要先将数据发送到设备。

Stream<Data> dataStream() {
  sendDataRequestToDevice();
  return _broadcastController.stream;
}

问题在于所有内容都是异步的,这意味着当返回流时,从设备发送的实际事件很可能已经消失。我正在寻找类似的东西:

Stream<Data> dataStream() {
  return _broadcastController.stream
    .doOnSubscribe(() => sendDataRequestToDevice()); // stolen from rxjava ;)
}

默认的流媒体库中是否存在类似的内容,而没有使用RxDart或类似内容。 (我只是不想为此目的使用它...)

3 个答案:

答案 0 :(得分:1)

如果您关心自己有多少个订户,则可能不应该使用广播流。广播流的基本思想是广播,而不知道(或关心)谁在听。 onListenonCancel回调最初不是广播控制器的一部分,它们会稍微破坏模型。它们确实允许您知道什么时候没人在听,但是仅此而已。

在这种情况下,我将创建自己的流来记录监听和取消。

class _ListenStream<T> extends Stream<T> {
  final Stream<T> _source;
  final void Function() _onListen; 
  final void Function() _onCancel;
  _ListenStream(this._source, this._onListen, this._onCancel);
  bool get isBroadcastStream => _source.isBroadcastStream;
  StreamSubscription<T> listen(void Function(T) onData, {
    Function onError, void Function() onDone, bool cancelOnError = false}) {
    if (_onListen != null) _onListen();
    return _ListenSubscription<T>(_source.listen(onData, 
        onError: onError, onDone: onDone, cancelOnError: cancelOnError),
        _onCancel);  
  }
}
class _ListenSubscription<T> extends StreamSubscription<T> {
  final _StreamSubscription<T> _source;
  final void Function() _onCancel;

  void onData(void handleData(T data)) { _source.onData(handleData); }
  void onError(Function handleError) { _source.onError(handleError); }
  void onDone(void handleDone()) { _source.onDone(handleDone); }

  void pause([Future resumeSignal]) { _source.pause(resumeSignal); }
  void resume() { _source.resume(); }
  Future<E> asFuture<E>([E defaultValue]) => _source.asFuture<E>(defaultValue);
  bool get isPaused => _source.isPaused;

  Future cancel() {
    var future = _source.cancel();
    if (_onCancel != null) future = future.whenComplete(_onCancel);
    return future;
  }
}

然后,不提供原始流,而是为客户提供原始流的_ListenStream包装器,以及要在监听和取消时调用的回调。

答案 1 :(得分:0)

您似乎正在寻找onListen

https://api.dartlang.org/stable/2.1.0/dart-async/StreamController/onListen.html

_broadcastController.onListen = () {
  _broadcastController.add('foo');
};

您还可以将处理程序传递给构造函数https://api.dartlang.org/stable/2.1.0/dart-async/StreamController/StreamController.html

答案 2 :(得分:0)

对于其他寻求解决方案的人:

我觉得这不是一个很好的解决方案,但是确实可以。请告诉我有更好的解决方案!

Stream<Data> dataStream() {
  return StreamGroup.merge([
        doOnSubscribe(() => sendDataRequestToDevice()),
        _broadcastController.stream
      ]);
}

Stream doOnSubscribe(void onSubscribe()) {
  StreamController controller;
  controller = StreamController(
    onListen: () {
      onSubscribe();
      controller.close();
    },
  );
  return controller.stream;
}

遗憾的是,由于其他问题,它无法完成我的BLE解决方案。