[英]RxJava- CombineLatest but only fire for one Observable's emission?
假設我有兩個可以隨時發出值的無限 Observable。 它們結合起來創建一個Observable<ProcessFileEvent>
。
Observable<Integer> selectedFileId= ...
Observable<MouseClick> buttonClick = ...
Observable<ProcessFileEvent> `processFileEvent` = Observable.combineLatest(selectedFileId, buttonClick, (s,b) -> {
//create ProcessFileEvent here
});
問題是我只希望 processFileEvent 在buttonClick
發出某些東西時發出,而不是selectedFileId
。 當輸入文件 ID 並啟動ProcessFileEvent
時,這絕對不是用戶期望的行為。 如何組合但僅在buttonClick
發出時發出?
使用withLatestFrom
:
Observable<Integer> selectedFileId= ...
Observable<MouseClick> buttonClick = ...
Observable<ProcessFileEvent> processFileEvent = buttonClick.withLatestFrom(selectedFieldId, (b,s) -> {
//create ProcessFileEvent here
});
它僅在第一個Observable
buttonClick
發出時發出。
使用.distinctUntilChanged()
上的MouseClick
的對象。 這樣,您只會在MouseClick
更改時獲取事件。
創建一個包含fileId
和mouseClick
:
static class FileMouseClick {
final int fileId;
final MouseClick mouseClick;
FileMouseClick(int fileId, MouseClick mouseClick) {
this.fileId = fileId;
this.mouseClick = mouseClick;
}
}
然后
Observable.combineLatest(selectedFileId, buttonClick,
(s,b) -> new FileMouseClick(s,b))
.distinctUntilChanged(f -> f.mouseClick)
.map(toProcessFileEvent())
您可以使用Observable.Join執行此操作。 特別注意這一段:
但是,我該怎么做才能確保這些窗口不重疊 - 這樣,一旦產生第二個值,我將不再看到第一個值? 好吧,如果我們從leftDurationSelector返回左側序列,那就可以了。 但是等等,當我們從leftDurationSelector返回序列時,它會嘗試創建另一個訂閱,這可能會引入副作用。 快速回答是發布和RefCount左側序列。 如果我們這樣做,結果看起來更像這樣。
left |-0-1-2-3-4-5|
right |---A---B---C|
result|---1---3---5
A B C
那個大理石圖是你想要的,其中selectedFileId是左序列,buttonClick是正確的序列。
這對我有用,缺少的部分是startWith()
運算符。 一旦你將它添加到可觀察對象中,它就會開始工作。
樣本
Observable.combineLatest(
firstObservable.observeDoors("1").startWith(emptyList<Door>()),
secondObservable.observeUnits("2").startWith( emptyList<Door>())
) { doors, units ->
ArrayList<Door>().apply {
addAll(units)
addAll(doors)
}
}.map {
//do something
}
這是因為 combine 需要所有源開始發出至少一個值,它會初始化 stream,然后只聽它的變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.