【问题标题】:Calling Drain() on a Stream never returns and the stream never closes在 Stream 上调用 Drain() 永远不会返回,并且流永远不会关闭
【发布时间】:2019-12-21 03:37:14
【问题描述】:

我在我的 Flutter 应用程序中按照 BLOC 模式使用 dart Streams,所以从逻辑上讲,每当我使用 Bloc 完成时,我都需要处理其中的所有流。

因此,在有状态小部件提供的 dispose 方法中,我正在调用 drain 方法,如下所示:

dispose() async {
    print('Started Dispose');

    await _mainStream.drain();

    print('_mainStream Drained');
  }

所以发生的情况是我看到第一个打印,但看不到第二个,这意味着我的流没有耗尽,如果我在收到新事件时收听流并打印一些东西,我仍然会在调试中看到该消息控制台即使我的 Bloc 已从小部件树中释放。

所以基本上我的流仍然存在于某个地方。我该如何解决这个问题,因为它让我发疯。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    要停止收听流媒体,请取消订阅,而不是致电 drain。 流可以是“永远的”,从某种意义上说,它们将继续发出事件,直到它们关闭。出于这个原因,尝试排空这样的流是危险的,因为它永远不会完成。

    下面是一个简单的示例,说明如何取消订阅:

    final foreverStream = Stream.periodic(Duration(milliseconds: 10), (i) => i);
    
    main() async {
      final subscription = foreverStream.listen((event) => print("EVENT: $event"));  
    
      await Future.delayed(Duration(milliseconds: 100));
    
      await subscription.cancel();
      print("Done");
    }
    

    如果您未能取消订阅,它会一直打印,或者直到您终止该进程。

    【讨论】:

    • 我也考虑过使用 StreamSubcription 并稍后取消订阅,但我认为排空和关闭流也可以,我会尝试在我的代码中实现这种方法,然后用结果回复你.谢谢我的帮助:)
    • Drain 只是监听并丢弃所有事件。它返回的未来仅在流关闭时完成。如果流正在进行(就像大多数在实践中一样),它将永远不会完成。
    • 很有意义,因为我正在收听 Firestore 流,这在逻辑上永远不会结束。我使用了 StreamSubscription 方法,效果很好,再次感谢您的澄清:D
    猜你喜欢
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2017-12-06
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多