试图弄清楚为什么它没有按我期望的顺序执行。我期望2是最后执行的程序,但是它会在其他所有操作完成之前完成。 无法理解为什么它在4点之后和收听流之前返回函数。
Future mainFn() async {
print('Listen 1');
Ob o = await listenFn();
print('Listen 2');
return await someFn(o);
}
Future<Ob> listenFn() async {
o = new Ob();
print('Listen 3');
Stream<Ct> stream = await getCt();
print('Listen 4');
stream.listen((Ct _ct) {
print('Listen 7');
if (!cts.contains(_ct)) {
setState(() {
cts.add(_ct);
});
}
}, onError: (a) {
print('Listen 8');
print(a);
}, onDone: () async {
print('Listen 9');
o = await addOb(cts); <-- This function returns Future<Ob>
});
await stream.drain();
print('Listen 14');
return o;
}
Future<Stream<Ct>> getCt() async {
print('Listen 5');
final String url = 'API_URL';
final client = new http.Client();
final request = http.Request('get', Uri.parse(url));
final streamedRest = await client.send(request);
print('Listen 6');
return streamedRest.stream
.transform(utf8.decoder)
.transform(json.decoder)
.map((data) => Helper.getData(data))
.expand((data) => (data as List))
.map((data) {
return Ct.fromJSON(data);
});
}
我要
I/flutter (22211): Listen 1
I/flutter (22211): Listen 3
I/flutter (22211): Listen 5
I/flutter (22211): Listen 6
I/flutter (22211): Listen 4
I/flutter (22211): Listen 2
I/flutter (22211): Listen 7 <-- 4 Ct items in the stream
I/flutter (22211): Listen 7
I/flutter (22211): Listen 7
I/flutter (22211): Listen 7
I/flutter (22211): Listen 9
I/flutter (22211): Listen 10 <-- added more of these along the way
I/flutter (22211): Listen 11
I/flutter (22211): Listen 12
I/flutter (22211): Listen 13
答案 0 :(得分:1)
以下是细分:
mainFn
,打印Listen 1
。mainFn
呼叫并等待listenFn
。listenFn
。打印Listen 3
。listenFn
呼叫并等待getCt
。getCt
。打印Listen 5
。getCt
呼叫并等待client.send
。client.send
完成工作并返回。getCt
恢复并打印Listen 6
。getCt
返回一个Stream
。listenFn
恢复并打印Listen 4
。listenFn
将监听器添加到Stream
。listenFn
不返回任何内容。mainFn
恢复并打印Listen 2
。mainFn
呼叫并等待someFn
。Stream
发出事件,触发侦听器回调。Listen 7
。Stream
最终完成并打印Listen 9
。您出错的地方是您希望listenFn
将返回onDone
回调的结果。 listenFn
不等待Stream
运行完成;它注册一个回调并立即返回。如果在代码上运行dartanalyzer
,应该收到一条警告,提示已声明listenFn
返回一个值,但从不返回任何内容。
答案 1 :(得分:0)
因此,如果将来有人偶然发现此问题,我就有机会找到解决方案。答案是使用await for
。
stream.listen()设置将在事件到达时放入事件队列中的代码,然后执行以下代码。
等待事件之间的挂起,并一直保持挂起状态,直到流完成为止,因此,紧随其后的代码将不会执行。
await for(String s in stream) { print(s); }