通过可观察的自身控制可观察的缓冲

时间:2016-05-09 10:05:53

标签: rx-scala

我试图自己切割可观察流,例如:

val source = Observable.from(1 to 10).share
val boundaries = source.filter(_ % 3 == 0)
val result = source.tumblingBuffer(boundaries)

result.subscribe((buf) => println(buf.toString))

Te输出是:

Buffer()
Buffer()
Buffer()
Buffer()

source可能会在到达boundaries之前在result行上进行迭代,因此它只会创建边界和生成的缓冲区,但是没有任何内容可以填写。

我的方法是使用publish / connect

val source2 = Observable.from(1 to 10).publish
val boundaries2 = source2.filter(_ % 3 == 0)
val result2 = source2.tumblingBuffer(boundaries2)

result2.subscribe((buf) => println(buf.toString))
source2.connect

这会产生输出:

Buffer(1, 2)
Buffer(3, 4, 5)
Buffer(6, 7, 8)
Buffer(9, 10)

现在我只需要隐藏connect来自外部世界,connectresult订阅时(我在课堂上这样做,我不想暴露)它)。类似的东西:

val source3 = Observable.from(1 to 10).publish
val boundaries3 = source3.filter(_ % 3 == 0)
val result3 = source3
          .tumblingBuffer(boundaries3)
          .doOnSubscribe(() => source3.connect)

result3.subscribe((buf) => println(buf.toString))

但是现在,doOnSubscribe动作永远不会被调用,因此发布的source永远不会被连接......

出了什么问题?

1 个答案:

答案 0 :(得分:1)

您使用publish解决方案走在了正确的轨道上。但是,有一个替代publish运算符,它将lambda作为Observable[T] => Observable[R]类型的参数(see documentation)。此lambda的参数是原始流,您可以安全地多次订阅。在lambda中,您可以根据自己的喜好转换原始流;在你的情况下,你过滤流缓冲它在那个过滤器上。

Observable.from(1 to 10)
    .publish(src => src.tumblingBuffer(src.filter(_ % 3 == 0)))
    .subscribe(buf => println(buf.toString()))

此运算符的最佳之处在于您之后无需调用connect之类的任何内容。