我有一个频繁值的流和一个慢的流。我希望将它们组合起来,但只在较慢的一个发出时才发出一个值。所以combineLatest
不起作用。
像这样:
a1
a2
b1
(a2,b1)
a3
a4
a5
b2
(a5,b2)
目前我这样做,是否有更清洁的方式?
withLatest[A,B](fast : Observable[A], slow : Observable[B]): Observable[(A,B)] =
Observable({ o =>
var last : A
fast.subscribe({a => last = a})
slow.subscribe({b => o.onNext((last,b))})
})
编辑:此运算符现在位于Rx中,名为withLatestFrom。
答案 0 :(得分:4)
你正在寻找的是我称之为“combinePrev”的组合器,它在API中不存在,但在许多情况下证明是非常必要的。 sample
运算符接近,但它不会合并两个流。 I've also missed "combinePrev" in RxJS。事实证明,“combinePrev”(“withLatest”)的实现很简单,只取决于地图和开关:
withLatest[A,B](fast : Observable[A], slow : Observable[B]): Observable[(A,B)] = {
val hotSlow = slow.publish.refCount
fast.map({a => hotSlow.map({b => (a,b)})}).switch
}
以下是在RxJS中实现的相同运算符的jsfiddle示例。
虽然运算符不在Rx中,但您可以使用隐式类,因此可以使用slow.withLatest(fast)
:
implicit class RXwithLatest[B](slow: Observable[B]) {
def withLatest[A](fast : Observable[A]) : Observable[(A,B)] = /* see above */
}
注意:slow
必须为hot
。如果slow
是一个寒冷的Observable,则withLatest
不起作用。