有没有办法在 dart 流获得第一个结果时收到通知?

All*_* Hu 8 dart flutter

我目前有一个async执行以下操作的函数:

  1. 初始化流
  2. 调用stream.listen()并提供监听流的函数。
  3. await以便流获得第一个结果。

以下是我的函数的一些伪代码:

Future<void> initStream() async {
  // initialize stream
  var stream = getStream();
  // listen
  stream.listen((result) {
    // do some stuff here
  });
  // await until first result
  await stream.first; // gives warning
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,似乎调用算作stream.first监听流,并且流不允许被多个...监听器监听?

我尝试了一种不同的方法,使用await Future.doWhile() 如下所示的方法:

bool gotFirstResult = false;
Future<void> initStream() async {
  var stream = getStream();
  stream.listen((result) {
    // do some stuff here
    gotFirstResult = true;
  });
  await Future.doWhile(() => !gotFirstResult);
}
Run Code Online (Sandbox Code Playgroud)

这对我不起作用,我仍然不知道为什么。已成功调用,但在这种情况下从未调用Future.doWhile()提供给的函数。stream.listen()

有没有办法等待流的第一个结果?(如果我没有很好地描述我的问题,我很抱歉。如果需要,我一定会添加其他详细信息。)提前致谢!

Pav*_*vel 11

一种方法是将流转换为广播流:

var stream = getStream().asBroadcastStream();
stream.listen((result) {
  // do some stuff here
});
await stream.first;
Run Code Online (Sandbox Code Playgroud)


Pav*_*vel 8

另一种不创建新流的方法是使用Completer。它允许您返回一个可以稍后完成(发送值)的 Future。调用者将能够像往常一样等待这个 Future。

简单的例子:

Future<int> getValueAsync() {
  var completer = Completer<int>();
  Future.delayed(Duration(seconds: 1))
    .then((_) {
      completer.complete(42);
    });
  return completer.future;
}
Run Code Online (Sandbox Code Playgroud)

相当于

Future<int> getValueAsync() async {
  await Future.delayed(Duration(seconds: 1));
  return 42;
}
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

Future<void> initStream() {
  var stream = getStream();
  var firstValueReceived = Completer<void>();
  stream.listen((val) {
    if (!firstValueReceived.isCompleted) {
      firstValueReceived.complete();
    }
    // do some stuff here
  });
  return firstValueReceived.future;
}
Run Code Online (Sandbox Code Playgroud)