首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步等待行为不正常

异步等待行为不正常
EN

Stack Overflow用户
提问于 2020-05-17 06:31:42
回答 2查看 82关注 0票数 0

试图找出为什么这不能按我所期望的顺序执行。我希望2是最后一个执行,但它是完成之前,所有其他运行。无法理解为什么在4点之后,在听流之前返回函数。

代码语言:javascript
复制
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);
  });
}

我得到了

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-30 03:44:18

所以如果有人在未来偶然发现这件事,我碰巧找到了解决这个问题的办法。答案是使用await for

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

等待事件之间的挂起,并一直这样做,直到流完成,所以在发生之前不会执行跟随它的代码。

代码语言:javascript
复制
await for(String s in stream) { print(s); }

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

票数 0
EN

Stack Overflow用户

发布于 2020-05-17 09:04:48

这是一个细分:

Listen 1.

  • mainFn

  • 输入mainFn,打印调用并等待listenFn.
  1. Enter listenFn。打印Listen 3.
  2. listenFn调用并等待getCt.
  3. Enter getCt。打印Listen 5.
  4. getCt调用和等待client.send.
  5. client.send完成其工作,returns.
  6. getCt恢复和打印Listen 6.
  7. getCt返回Stream.
  8. listenFn简历,并打印Listen 4.
  9. listenFnStream.
  10. listenFn添加侦听器返回nothing.
  11. mainFn简历和打印Listen 2someFn.
  12. The mainFn呼叫并等待Stream发布事件,触发侦听器callback.
  13. The侦听器回调打印每个事件的Listen 7

错误之处在于,您期望listenFn将返回onDone回调的结果。listenFn不等待Stream运行完成;它注册一个回调并立即返回。如果在代码上运行dartanalyzer,应该会收到一个警告,指出listenFn被声明为返回值,但从不返回任何内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61847868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档