异步等待行为异常

时间:2020-05-17 06:31:42

标签: dart

试图弄清楚为什么它没有按我期望的顺序执行。我期望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

2 个答案:

答案 0 :(得分:1)

以下是细分:

  1. 输入mainFn,打印Listen 1
  2. mainFn呼叫并等待listenFn
  3. 输入listenFn。打印Listen 3
  4. listenFn呼叫并等待getCt
  5. 输入getCt。打印Listen 5
  6. getCt呼叫并等待client.send
  7. client.send完成工作并返回。
  8. getCt恢复并打印Listen 6
  9. getCt返回一个Stream
  10. listenFn恢复并打印Listen 4
  11. listenFn将监听器添加到Stream
  12. listenFn 不返回任何内容
  13. mainFn恢复并打印Listen 2
  14. mainFn呼叫并等待someFn
  15. Stream发出事件,触发侦听器回调。
  16. 侦听器回调为每个事件打印Listen 7
  17. Stream最终完成并打印Listen 9

您出错的地方是您希望listenFn将返回onDone回调的结果。 listenFn不等待Stream运行完成;它注册一个回调并立即返回。如果在代码上运行dartanalyzer,应该收到一条警告,提示已声明listenFn返回一个值,但从不返回任何内容。

答案 1 :(得分:0)

因此,如果将来有人偶然发现此问题,我就有机会找到解决方案。答案是使用await for

stream.listen()设置将在事件到达时放入事件队列中的代码,然后执行以下代码。

等待事件之间的挂起,并一直保持挂起状态,直到流完成为止,因此,紧随其后的代码将不会执行。

await for(String s in stream) { print(s); }

信用:https://stackoverflow.com/a/42613676/12689749