Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 当有人订阅时做些什么?_Asynchronous_Dart_Stream - Fatal编程技术网

Asynchronous 当有人订阅时做些什么?

Asynchronous 当有人订阅时做些什么?,asynchronous,dart,stream,Asynchronous,Dart,Stream,我有一个BLE设备的数据流的广播流 为了从该流中获取数据,我需要在之前将数据发送到设备 Stream<Data> dataStream() { sendDataRequestToDevice(); return _broadcastController.stream; } streamdatastream(){ sendDataRequestToDevice(); 返回_broadcastController.stream; } 问题是,所有内容都是异步的,这意味着当返回

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

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

Stream<Data> dataStream() {
  sendDataRequestToDevice();
  return _broadcastController.stream;
}
streamdatastream(){
sendDataRequestToDevice();
返回_broadcastController.stream;
}
问题是,所有内容都是异步的,这意味着当返回流时,很可能设备发送的实际事件已经消失了。我正在搜索以下内容:

Stream<Data> dataStream() {
  return _broadcastController.stream
    .doOnSubscribe(() => sendDataRequestToDevice()); // stolen from rxjava ;)
}
streamdatastream(){
return\u broadcastController.stream
.doOnSubscribe(()=>sendDataRequestToDevice());//从rxjava窃取)
}

默认流媒体库中是否有类似的内容,而不使用RxDart或类似工具。(我只是不想仅仅为了这个目的而使用它…

似乎您正在寻找
onListen


您还可以为搜索解决方案的其他所有人将处理程序传递给构造函数:

我认为这不是一个好的解决方案,但它确实起到了作用。请告诉我有更好的解决办法

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;
}
streamdatastream(){
返回StreamGroup.merge([
doOnSubscribe(()=>sendDataRequestToDevice()),
_广播控制器.stream
]);
}
流doOnSubscribe(在Subscribe()上无效){
流量控制器;
控制器=流控制器(
onListen:(){
onSubscribe();
controller.close();
},
);
返回控制器.stream;
}

遗憾的是,由于其他问题,它不能满足我的BLE解决方案的要求。

如果你关心你有多少订户,你可能不应该使用广播流。广播流的基本思想是,它在不知道(或不关心)谁在听的情况下进行广播。
onListen
onCancel
回调最初不是广播控制器的一部分,它们稍微破坏了模型。它们确实让你知道什么时候没有人在听,但仅此而已

在这种情况下,我会制作自己的流,记录侦听和取消

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;
  }
}
class\u ListenStream扩展流{
最终流源;
最终void函数()\u onListen;
最终无效函数()_onCancel;
_ListenStream(this.\u source,this.\u onListen,this.\u onCancel);
bool get isBroadcastStream=>\u source.isBroadcastStream;
流函数(T)onData{
函数onError,void函数()onDone,bool cancelOnError=false}){
如果(_onListen!=null)_onListen();
return _ListenSubscription(_source.listen(onData,
onError:onError,onDone:onDone,cancelOnError:cancelOnError),
_onCancel);
}
}
类_ListenSubscription扩展了StreamSubscription{
最终订阅来源;
最终无效函数()_onCancel;
void onData(void handleData(T data)){u source.onData(handleData);}
void onError(函数handleError){u source.onError(handleError);}
void onDone(void handleDone()){u source.onDone(handleDone);}
无效暂停([Future resumeSignal]){{u source.pause(resumeSignal);}
void resume(){u source.resume();}
Future asFuture([E defaultValue])=>\u source.asFuture(defaultValue);
bool get isPaused=>\u source.isPaused;
未来取消(){
var future=_source.cancel();
如果(\u onCancel!=null)future=future.whenComplete(\u onCancel);
回归未来;
}
}

然后,您不提供原始流,而是为您的客户提供原始流的
\u ListenStream
包装,以及您希望在listen和cancel上调用的回调。

不,这不是我要找的。构造函数上的onListen会在第一个订阅者订阅后调用一次。我需要一个在用户订阅时总是被调用的东西,而不是一次。每次监听流时都应该调用它。我很确定,因为我自己用过几次这个方法来立即将最后一个值传递给新的接收者。如果它不起作用,可能与广播有关。我知道你在说什么。不,这不是我需要的。这些方法(onListen、onCancel)用于启动和关闭广播。这意味着,如果您在该广播上有10个订户,那么onListen方法将被调用一次。当我按照你的建议去做(只是尝试了一下),我就会覆盖这些广播回调,这不是我想要的。只要有人订阅广播,我就要回电话。(是的,这很可能与广播有关,因为如果你不在广播中,这些方法是免费使用的)我不认为还有别的东西。我建议你提问,或者只是发布一个链接到这个问题。这个软件包的维护人员对streams很在行。
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;
  }
}