我是RxJava的新手,我一直试图以循环方式组合多个可观察对象。
所以,想象一下你有三个可观测量:
o1: --0---1------2--
o2: -4--56----------
o3: -------8---9----
以循环方式组合这些会给你类似的东西:
r : --04---815-9-26-
最好的方法是什么? 由于它看起来像RxJava,RxScala等几乎共享API,任何语言的答案都应该没问题。 :)
谢谢, Matija
答案 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
这正是你想要的。
这种方法的问题在于它会阻塞,直到来自每个三个源的值到达,但如果你很酷,我认为这是迄今为止最简单的解决方案。我很好奇,你的用例是什么?
这实际上是一个有趣的问题。这是另一种看法,它将为另一种做出一个缺点。
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。如果你很好奇,你可以关注它。