在 Dart 中保存流的最后发出的值

Posted

技术标签:

【中文标题】在 Dart 中保存流的最后发出的值【英文标题】:Save last emitted value of stream in Dart 【发布时间】:2019-05-21 02:00:09 【问题描述】:

我在 Flutter 中使用 Firestore 和底部导航栏制作了一个应用程序。问题是,当我在选项卡之间切换时,每次都会调用 build 方法。 build 方法从 firestore 下载数据。因此,当我切换标签时,应用程序会闪烁(旋转条显示的时间很短)。我试图通过将 firestore 流移动到构造函数来解决这个问题。但是,由于流可以在构建方法之前发出,因此它会永远加载。

一种解决方案可能是保存发出的最后一个值。我尝试使用 Rx 中的 shareReplay 方法解决此问题,但它们尚未在 RxDart 中实现。那么,实现这一点的最佳做法是什么?

【问题讨论】:

【参考方案1】:

在当前接受的答案中,RXDart 中的 Observable 类现已弃用。相反,您可以使用BehaviorSubject,但最好使用ValueConnectableStream,如下所示:

final newStream = ValueConnectableStream(yourStream).autoConnect()

请参阅RXDart docs 了解更多信息。

【讨论】:

【参考方案2】:

在 rxDart 中将 stream 转换为 BehaviorSubject

BehaviorSubject<Data> _subject = BehaviorSubject<Data>();

stream.listen((x) => _subject.add(x));

【讨论】:

【参考方案3】:

我在发布模式下运行了 Flutter 应用程序,延迟消失了,没有进行任何修改。

【讨论】:

这可能意味着您在生产速度较慢或配置不同的设备上存在竞争条件?【参考方案4】:

使用 rxdart 的 shareValue 运算符:

final observable = Observable(yourStream).shareValue();

在内部,此运算符使用BehaviorSubject。只要有一个订阅者,它就会订阅流(它只会订阅一次),并在没有更多订阅者时取消订阅(并处置主题)。

另外,正如您所说,您必须在 initState 或类似方法(而不是 build 方法!)中创建 observable。 observable 应该存储在State 中的一个字段中。

【讨论】:

【参考方案5】:

您可以查看 rxdart 中的 BehaviorSubject。根据文档

已添加到该主题的最新项目将发送给该​​主题的任何新听众。

【讨论】:

谢谢,但是如何将 dart 流转换为行为主题? BehaviorSubject 实现了 ValueObservable,它实现了扩展 Stream 的 Observable。 BehaviorSubject 可以做流可以做的所有事情以及更多,所以它应该只是一个直接的替代品。 当然,但是firestore插件返回一个dart流,我怎样才能用它来做一个behaviorsubject? @SondreSørbye 你知道如何将 dart 流转换为 behaviorsubject 吗?

以上是关于在 Dart 中保存流的最后发出的值的主要内容,如果未能解决你的问题,请参考以下文章

Dart异步编程之Stream

编辑器在保存时打开 main.dart

如何保存 CompletionHandler 返回的值?

使用带有内存流的 c# 在控制台应用程序中保存图像时,GDI + 中发生一般错误

如何使用 dart/flutter 中的共享首选项保存和获取列表列表

Flutter/Dart:将图像文件保存到“/storage/emulated/0/Picture/AppFolder/”