【发布时间】:2018-12-16 05:02:56
【问题描述】:
我想知道如何在 RX 中做到这一点。
T他的实际用例是LowerLevelEvent(val userId: String)到HigherLevelEvent(val user: User)的映射,其中User是由observable提供的,所以它可以发出n次,所以例子输出
LowerLevelEvent1(abc) -> HigherLevelEvent1(userAbc(nameVariation1)
LowerLevelEvent2(abc) -> HigherLevelEvent2(userAbc(nameVariation1)
LowerLevelEvent3(abc) -> HigherLevelEvent3(userAbc(nameVariation1)
LowerLevelEvent4(abc) -> HigherLevelEvent4(userAbc(nameVariation1)
HigherLevelEvent4(userAbc(nameVariation2)
HigherLevelEvent4(userAbc(nameVariation3)
所以我天真的解决方案是使用 combineLatest。因此,虽然 userId 未更改,但用户 observable 已订阅,即当新的 lowerLevelEmits 及其 userId 未更改时未重新订阅
val _lowerLevelEventObservable: Observable<LowerLevelEvent> = lowerLevelEventObservable
.replayingShare()
val _higherLevelEventObservable: Observable<HigherLevelEvent> = Observables
.combineLatest(
_lowerLevelEventObservable,
_lowerLevelEventObservable
.map { it.userId }
.distinctUntilChanged()
.switchMap { userRepository.findByIdObservable(it)
) { lowerLevelEvent, user -> createHigherLevelInstance... }
但是,这存在故障问题,因为 combineLatest 中的两个源都来自同一个 observable。
然后我想到了
lowerLevelObservable.
.switchMap { lowerLevelEvent ->
userRepository.findByIdObservable(lowerLevelEvent.userId)
.map { user -> createHigherLevelInstance... }
}
但是,如果 lowerLevelObservable 快速发射,这可能会中断,并且由于用户 observable 可能需要一些时间,因此可以跳过给定的 lowerLevelX 事件,而我不能这样做。它还重新订阅用户可观察的每个发射,这是浪费的,因为它很可能不会改变
那么,也许是 concatMap?这存在用户可观察对象未完成的问题,因此 concatMap 不起作用。
有人知道吗?
非常感谢
// 说明: 基本上它的 A 变体 (A1, A2..) 到 A' 变体 (A1', A2'..) 的映射,同时将查询对象附加到它,其中查询是可观察的,因此它可能会在映射后重新发出,所以AX' 需要重新发送新的查询结果。但是查询很冷,没有完成
例如A1(1) -> A1'(user1), A2(1) -> A2'(user1), A3(1) -> A3'(user1) -- 现在有人在应用程序的其他地方更改了 user1,所以下一个发出是A3'(user1')
【问题讨论】:
-
你想做什么让我很困惑。也许你可以使用
concatMap和里面的userRepository.findByIdObservable(...).take(1)? -
@martin id 喜欢将下层事件映射到上层事件,在哪里映射到上层我需要通过下层事件中的 userId 查询用户。但是,在整个过程中数据库可能会发生变化,所以我需要用新的用户值重新发送更高级别的事件
-
我特别不明白这一点,“......鉴于lowerLevelX事件可以跳过,我不能。”为什么您想要已被取代的事件?
-
@DanielT。因为较低级别的事件是代数数据类型,我需要查看所有即将到来的类型
-
基本上它的 A 变体 (A1, A2..) 到 A' 变体 (A1', A2'..) 的映射,同时将查询对象附加到它,其中查询是可观察的,因此它可能映射完成后重新发送,因此需要用新的查询结果重新发送 AX'
标签: rxjs rx-java reactive-programming rx-swift reactive