这是一个简单程序的基础,该程序使用StreamController侦听某些输入流,并在其自己的流上输出一些其他数据作为响应:

import 'dart:async';

main() async {
    var c = StreamController(
            onListen: (){},
            onPause: (){},
            onResume: (){},
            onCancel: (){});

    print("start");
    await for (var data in c.stream) {
            print("loop");
    }

    print("after loop");
}

输出:
$ dart cont.dart
start
$ dart

为什么此代码在等待行时立即退出,而不执行print(“loop”)或print(“after loop”)?

注意:在原始程序中,onListen()将接收输入流并对其进行订阅。循环实际上一直有效,直到在输入流上调用subscription.cancel()时,该循环也突然退出,而没有任何清理的机会。

最佳答案

我对此感到惊讶,但随后所有的async/await代码又都转换为.then(),似乎所有内容都无法完美翻译。

看来这是答案的一部分:您需要在另一个任务中关闭流才能退出await forHere是先前的相关问题。由于我们没有关闭它,因此await for之后的行不会执行。下面是避免这种情况的示例:

import 'dart:async';

main() async {
  var c = StreamController(
      onListen: () {},
      onPause: () {},
      onResume: () {},
      onCancel: () {});

  print("start");
  await Future.wait(<Future>[producer(c), consumer(c)]);

  print("after loop");
}

Future producer(StreamController c) async {
  // this makes it print "loop" as well
  // c.add("val!");
  await c.close();
}

Future consumer(StreamController c) async {
  await for (var data in c.stream) {
    print("loop");
  }
}

打印:
start
after loop

所以,故事的寓意是
  • 切勿让StreamController处于无人看管的状态,否则会发生怪异的事情。
  • 您等待的一些异步函数会破坏您的代码,甚至绕过try / finally块!

  • 我以为我知道异步/等待内幕,但是第二点现在让我感到恐惧。

    关于dart - 在Dart中,为什么要等待琐碎的(“empty”)StreamController流立即退出程序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61703133/

    10-10 17:56
    查看更多