refactoring - 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()
}
}
我认为无需订阅intSubject
inside booleanSubject.switchMap
:
booleanSubject.map { Triple(i,"$s:$it", i) }
我只是想知道是否存在原始代码会产生与简化代码不同的结果的极端情况。
解决方案
你为什么不把所有三个主题都组合成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
应该始终首先调用。
推荐阅读
- ruby-on-rails - 为什么使用 Rails 保存副本数据时 `after_save` 不起作用?
- python - 如何将列表中的元素拆分为两个元素?
- c# - 如何在 C# 类中创建和启动 SignalR 集线器连接
- mysql - 使用内部选择的结果从单独的表中进行选择
- amazon-web-services - 电子邮件作为 DynamoDB 中客户订单的主键?
- python - 设想分解枚举的列表理解
- ssl - Certbot - 我如何选择 DNS 插件?
- docker - 容器内容未使用 docker volume 复制到 docker 主机
- excel - 循环遍历所有打开的工作簿时,代码在一个工作簿后退出循环
- php - 无法使用 shell_exec 在本地服务器上的 php 上执行 python 文件