结合可观察量的循环法

时间:2015-02-23 13:50:39

标签: scala rx-java

我是RxJava的新手,我一直试图以循环方式组合多个可观察对象。

所以,想象一下你有三个可观测量:

o1: --0---1------2--
o2: -4--56----------
o3: -------8---9----

以循环方式组合这些会给你类似的东西:

r : --04---815-9-26-

最好的方法是什么? 由于它看起来像RxJava,RxScala等几乎共享API,任何语言的答案都应该没问题。 :)

谢谢, Matija

2 个答案:

答案 0 :(得分:3)

默认情况下,RxJava没有这样的运算符。最接近的是使用与节奏良好的源合并,因为它使用循环法来收集值,但不能依赖此属性。为什么你需要这种循环行为?

最好的办法是手动实现此行为。 Here is an example没有背压支持。

答案 1 :(得分:1)

有一种方法实现起来非常简单,并且几乎正是你想要的 - 只需压缩三个源可观察对象,然后每次新的三元组时从压缩的observable中发出三个值到达。

转换为RxScala

val o1 = Observable.just(1, 2, 3)
val o2 = Observable.just(10, 20, 30)
val o3 = Observable.just(100, 200, 300)

val roundRobinSource = Observable
    .zip(Observable.just(o1, o2, o3))
    .flatMap(Observable.from[Int])

roundRobinSource.subscribe(println, println)

给你

1
10
100
2
20
200
3
30
300

这正是你想要的。

这种方法的问题在于它会阻塞,直到来自每个三个源的值到达,但如果你很酷,我认为这是迄今为止最简单的解决方案。我很好奇,你的用例是什么?

更新,拿#2

这实际上是一个有趣的问题。这是另一种看法,它将为另一种做出一个缺点。

import rx.lang.scala.{Subject, Observable}

val s1 = Subject[Int]()
val s2 = Subject[Int]()
val s3 = Subject[Int]()

val roundRobinSource3 = s1.publish(po1 ⇒ s2.publish(po2 ⇒ s3.publish(po3 ⇒ {
  def oneRound: Observable[Int] = po1.take(1) ++ po2.take(1) ++ po3.take(1)
  def all: Observable[Int] = oneRound ++ Observable.defer(all)
  all
})))

roundRobinSource3.subscribe(println, println, () ⇒ println("Completed"))

println("s1.onNext(1)")
s1.onNext(1)
println("s2.onNext(10)")
s2.onNext(10)
println("s3.onNext(100)")
s3.onNext(100)
println("s2.onNext(20)")
s2.onNext(20)
println("s1.onNext(2)")
s1.onNext(2)
println("s3.onNext(200)")
s3.onNext(200)
println("s1.onCompleted()")
s1.onCompleted()
println("s2.onCompleted()")
s2.onCompleted()
println("s3.onCompleted()")
s3.onCompleted()
println("Done...")

给你

s1.onNext(1)
1
s2.onNext(10)
10
s3.onNext(100)
100
s2.onNext(20)
s1.onNext(2)
2
20
s3.onNext(200)
200
s1.onCompleted()
s2.onCompleted()
s3.onCompleted()
Done...

它没有阻止,它是循环的,但是......它也没有完成:(你可以使用takeUntil,{{1}以有状态的方式完成它}和Subject如果你需要它,但是..

至于机制,它使用doOnComplete的某种神秘行为来跟踪已发出的事物。当@lopar回答我自己的问题Implementing a turnstile-like operator with RxJava时,我最初指的是它。

publish的行为对我来说实际上是个谜,我在这里发布了一个问题:https://github.com/ReactiveX/RxJava/issues/2775。如果你很好奇,你可以关注它。