Идентичные наблюдаемые внутри switchMap

#refactoring #rx-java2

#рефакторинг #rx-java2

Вопрос:

Пожалуйста, взгляните на следующий код:

 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()
    }

}
 

Я думаю, что нет необходимости подписываться на intSubject inside booleanSubject.switchMap :

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

Мне просто интересно, есть ли какие-либо крайние случаи, когда исходный код даст результат, отличный от упрощенного кода.

Ответ №1:

Почему бы вам просто не объединить все три объекта в 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 потому что они всегда должны вызываться первыми.