我有一个“外部”可观察物和一个“内部”可观察物的缓存。我选择哪个“内部”可观察值取决于“外部”可观察到的输出。当它们中的任何一个发生变化时,我都想将它们的结果合并。如果“外部”或“内部”更改,我想合并新值。我正在尝试使用flatMap进行此操作,但是遇到了触发太多事件(即重复)的问题。
fun test() {
val outerObs = Observable.interval(3, TimeUnit.SECONDS)
val innerObsCache = mapOf(
0L to Observable.interval(0, 1, TimeUnit.SECONDS).map { "zero:$it" }.share(),
1L to Observable.interval(0, 1, TimeUnit.SECONDS).map { "one:$it" }.share()
)
outerObs
.flatMap { outerVal ->
innerObsCache[outerVal % 2]!!.map { "Outer($outerVal):Inner($it)" }
}.subscribe({ combinedResult -> println("$now $combinedResult") })
}
private val now get() = SimpleDateFormat("HH:mm:ss").format(Date())
输出类似
00:17:36 Outer(0):Inner(zero:0)
00:17:37 Outer(0):Inner(zero:1)
00:17:38 Outer(0):Inner(zero:2)
00:17:39 Outer(1):Inner(one:0)
00:17:39 Outer(0):Inner(zero:3)
您会注意到,我在00:17:39
上得到两个输出。我真正想要发生的是这样的输出
00:17:36 Outer(0):Inner(zero:0)
00:17:37 Outer(0):Inner(zero:1)
00:17:38 Outer(0):Inner(zero:2)
00:17:39 Outer(1):Inner(one:0)
似乎我的问题是我的缓存的索引0处的内部可观察的对象。可观察的映射仍在自动售卖,因此导致发送了附加值。我没有看到如何发生这种情况,因为当我想切换到另一个观察对象时,实际上还没有观察到的东西完成。随着时间的流逝,这个问题变得更加严重,因为每个outerObs出售都会导致更多不希望的重复。
我确定我应该在这里使用其他一些RX技术来获得期望的结果,但是可以使用一些指导。
答案 0 :(得分:1)
弄清楚。给定用例,我使用了错误的运算符。
switchMap
完成了我想要的。当外部可观测值省略新值时,它将取消订阅内部可观测值。
outerObs
.switchMap { outerVal ->
innerObsCache[outerVal % 2]!!.map { "Outer($outerVal):Inner($it)" }
}.subscribe({ combinedResult -> println("$now $combinedResult") })
产生所需的输出
00:19:53 Outer(0):Inner(zero:0)
00:19:54 Outer(0):Inner(zero:1)
00:19:55 Outer(0):Inner(zero:2)
00:19:56 Outer(1):Inner(one:0)
What is the difference between flatmap and switchmap in RxJava?