通过flatMap嵌套的可观察项输出重复项

时间:2018-06-19 22:31:23

标签: rx-java rx-java2

我有一个“外部”可观察物和一个“内部”可观察物的缓存。我选择哪个“内部”可观察值取决于“外部”可观察到的输出。当它们中的任何一个发生变化时,我都想将它们的结果合并。如果“外部”或“内部”更改,我想合并新值。我正在尝试使用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技术来获得期望的结果,但是可以使用一些指导。

1 个答案:

答案 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?