我有点RxJava新手。我已经掌握了它,但是有一种情况我不太满意。假设我有一对不同类型的Observable,它们旨在一起工作。例如:
val list: Observable<List<MyClass>>
val indexIntoList: Observable<Int>
所以,我需要成对观察它们,以便观察者在 列表或 indexIntoList得到更新时被发现。现在我的解决方案是这样的:
var lastListUsed: List<MyClass> = ArrayList()
var lastIndexUsed = -1
val syncObject = Object()
init {
list.subscribe(object: Observer<List<MyClass>>{
.
.
.
override fun onNext(t: List<MyClass>)
{
FunctionOnMyClass(t, lastIndexUsed)
}
})
indexIntoList.subscribe(object: Observer<Int>{
.
.
.
override fun onNext(t: Int)
{
FunctionOnMyClass(lastListUsed, t)
}
})
}
fun FunctionOnMyClass(list: List<MyClass>, index: Int)
{
synchronized(syncObject)
{
lastListUsed = list
lastIndexUsed = index
.
.
.
}
}
我曾想过要做这样的事情:
var lastMyClass = DefaultMyClass()
list.doOnNext{listVersion ->
indexIntoMap.map{ index ->
if(index in listVersion.indices)
listVersion[index]
else
lastMyClass
}.subscribe(object: Observer<MyClass>{
.
.
.
override fun onNext(t: MyClass)
{
lastMyClass = t
.
.
.
}
})
}
但是,如果我正确理解,要使用此方法,则每次外部Observable更新时,都必须将Disposable放在内部Observable上。我宁愿不那样做。有没有一种首选的方式来处理这种情况?我是否应该对外部Observable的每次更新都处置该Disposable?
答案 0 :(得分:3)
我认为您正在寻找combineLastest
运算符:
当两个Observable之一发射一个项目时,通过指定的函数合并每个Observable发射的最新项目,并根据此函数的结果发射项目
以下是实现示例:
val myListObservable = ...
val myIndexObservable = ...
disposable = Observable.combineLatest(myListObservable, myIndexObservable, BiFunction { list: List<YourType>, index: Int ->
list to index
})
然后,您可以直接处理最后一个列表以及每个可观察到的Pair<List<YourType>,Int>
发出的las索引
如果您需要等待每个可观察对象发出彼此配对的元素,则应使用zip
通过指定的函数将多个Observable的发射合并在一起,并根据此函数的结果针对每种组合发射单个项目
您可以在图中看到,第二个可观察对象最后发出C
和D
。但是第一个可观察对象要花一些时间才能发出3
,然后发出4
。结果对将等待,直到另一个可观察到的对象发出要与之配对的元素。
实现与上述相同,将combineLastest
替换为zip
。
答案 1 :(得分:1)
如果您想收听两个可观察对象的最新事件,请查看Broker.IDENT=Info.ROWID
运算符:http://rxmarbles.com/#combineLatest
每次可观察对象中的一个发出新值时它都会发出,但每个源都发出至少一个事件后它将立即开始。
combineLatest