如何在Dart中嵌套流(将流映射到流事件)?

时间:2020-05-03 05:14:03

标签: flutter dart dart-async

类似于this Flutter question,我想嵌套 Stream s。
在Flutter中,这可以通过嵌套StreamBuilder轻松实现,但是,我不想使用小部件。相反,我想单独使用 Dart 解决问题。 (此处嵌套表示一个流取决于另一个流中的值,这些值应组合在一起)

让我来说明问题:

Stream streamB(String a);

streamA: 'Hi' --- 'Hello' ---- 'Hey'

如您所见,我有一个streamA不断发出事件,还有一个streamBstreamA发出的事件 产生。在streamC中,我想从streamB中获取有关每个事件的信息。

常规流映射

如果我使用的是valueB而不是streamB,我可以简单地使用streamA.map((event) => valueB(event)),但是Stream.map只能处理同步值。
还有Stream.asyncMap,仅适用于Future s。
然后,还有 Stream.expand,但这仅适用于同步可迭代对象。

1 个答案:

答案 0 :(得分:1)

Stream.asyncExpand

实际上有一个Stream.asyncExpand method

streamC = streamA.asyncExpand((event) => streamB(event));

但是,这样做的问题是,如果子流(streamC),结果流(streamA)仅会移至源流(streamB)中的下一个事件。第一个活动已结束。对于Cloud Firestore,这将永远无法工作,因为子流不会关闭。

Stream.concurrentAsyncExpand

幸运的是,这里有stream_transform package

streamC = streamA.concurrentAsyncExpand((event) => streamB(event));

此软件包提供了并发的 async 扩展功能。这样,结果流就不会等待子流关闭。

但是,这样做的缺点是,在接收到源流中的新事件时,先前的子流不会自动关闭。
因此,这对于Cloud Firestore也没有用。

Stream.switchMap

也来自stream_transform包:

streamC = streamA.sequentialAsyncExpand((event) => streamB(event));

这解决了我上面概述的问题。