首页 > 解决方案 > switchMap 中的相同 Observable

问题描述

请看下面的代码:

class FooImplTest {

    @Test
    fun sample1() {
        val booleanSubject = BehaviorSubject.create<Boolean>()
        val intSubject = BehaviorSubject.create<Int>()
        val stringSubject = BehaviorSubject.create<String>()

        val combineSecondAndThird = Observable.combineLatest(intSubject, stringSubject,
            { t1, t2 -> Pair(t1, t2) })

        intSubject.onNext(1)
        stringSubject.onNext("my str")

        booleanSubject.onNext(true)

        val o1 = combineSecondAndThird
            .switchMap { pair ->
                val i = pair.first
                val s = pair.second

                booleanSubject.switchMap {
                    intSubject.map { secondVal2 -> Triple(i,
                        "$s:$it", secondVal2) }
                }
            }
            .test()
            .assertValue(Triple( 1, "my str:true", 1))

        intSubject.onNext(3)

        o1.assertValueAt(1, Triple( 3, "my str:true", 3))
            .dispose()
    }

}

我认为无需订阅intSubjectinside booleanSubject.switchMap

booleanSubject.map { Triple(i,"$s:$it", i) }

我只是想知道是否存在原始代码会产生与简化代码不同的结果的极端情况。

标签: refactoringrx-java2

解决方案


你为什么不把所有三个主题都组合成combineLatest,就像下面的例子一样?

@Test
fun sample1() {
    val booleanSubject = BehaviorSubject.create<Boolean>()
    val intSubject = BehaviorSubject.create<Int>()
    val stringSubject = BehaviorSubject.create<String>()

    val combined = Observable.combineLatest(
        intSubject,
        stringSubject,
        booleanSubject,
        Function3<Int, String, Boolean, Triple<Int, String, Int>> { i, s, b ->
            Triple(i, "$s:$b", i)
        })

    intSubject.onNext(1)
    stringSubject.onNext("my str")

    booleanSubject.onNext(true)

    val test = combined
        .test()
        .assertValue(Triple(1, "my str:true", 1))

    intSubject.onNext(3)

    test.assertValueAt(1, Triple(3, "my str:true", 3))
        .dispose()
}

和以前一样,测试通过了。当所有值都是同步发出时,这无关紧要,因为combineSecondAndThird#switchMap应该始终首先调用。


推荐阅读