我目前有一个执行以下操作的async
函数:
stream.listen()
并提供侦听流的功能。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
}
不幸的是,似乎调用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);
}
这对我不起作用,我仍然不知道为什么。 Future.doWhile()
已成功调用,但是在这种情况下从未调用提供给stream.listen()
的函数。
有没有办法等待流的第一个结果? (对不起,如果我对问题的描述不够充分,我肯定会在需要时添加其他详细信息。) 预先感谢!
答案 0 :(得分:1)
一种方法是将流转换为广播流:
var stream = getStream().asBroadcastStream();
stream.listen((result) {
// do some stuff here
});
await stream.first;
答案 1 :(得分:1)
另一种无需创建新流的方法是使用Completer。它允许您返回一个Future,以后可以 complete (发送值)。呼叫者将能够照常等待此Future。
简单的例子:
Future<int> getValueAsync() {
var completer = Completer<int>();
Future.delayed(Duration(seconds: 1))
.then((_) {
completer.complete(42);
});
return completer.future;
}
等同于
Future<int> getValueAsync() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
在您的情况下:
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;
}