如何在 Dart 中嵌套流(将流映射到流事件)?
How do I nest Streams in Dart (map Streams to Stream events)?
类似于我想nestStream
s.
在 Flutter 中,这可以通过嵌套 StreamBuilder
轻松实现,但是,我不想使用小部件。相反,我想单独解决 Dart 中的问题。 (这里嵌套意味着一个流依赖于另一个流的值,这些应该合并)
让我来说明问题:
Stream streamB(String a);
streamA: 'Hi' --- 'Hello' ---- 'Hey'
如您所见,我有一个 streamA
持续发出事件,还有一个 streamB
从 streamA
的事件中产生 发出。在 streamC
中,我想更新 来自 streamB
的每个事件 。
常规流映射
如果我有 valueB
而不是 streamB
,我可以简单地使用 streamA.map((event) => valueB(event))
,但是,Stream.map
只能处理同步值。
还有 Stream.asyncMap
,但是,它只适用于 Future
s。
然后,还有 also Stream.expand
,但这仅适用于 synchronous 迭代器。
Stream.asyncExpand
实际上有一个Stream.asyncExpand
method:
streamC = streamA.asyncExpand((event) => streamB(event));
但是,如果子流(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));
这解决了我上面概述的问题。
类似于Stream
s.
在 Flutter 中,这可以通过嵌套 StreamBuilder
轻松实现,但是,我不想使用小部件。相反,我想单独解决 Dart 中的问题。 (这里嵌套意味着一个流依赖于另一个流的值,这些应该合并)
让我来说明问题:
Stream streamB(String a);
streamA: 'Hi' --- 'Hello' ---- 'Hey'
如您所见,我有一个 streamA
持续发出事件,还有一个 streamB
从 streamA
的事件中产生 发出。在 streamC
中,我想更新 来自 streamB
的每个事件 。
常规流映射
如果我有 valueB
而不是 streamB
,我可以简单地使用 streamA.map((event) => valueB(event))
,但是,Stream.map
只能处理同步值。
还有 Stream.asyncMap
,但是,它只适用于 Future
s。
然后,还有 also Stream.expand
,但这仅适用于 synchronous 迭代器。
Stream.asyncExpand
实际上有一个Stream.asyncExpand
method:
streamC = streamA.asyncExpand((event) => streamB(event));
但是,如果子流(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));
这解决了我上面概述的问题。