RxJava- CombineLatest, но только огонь для одного наблюдаемого излучения?

Скажем, у меня есть две бесконечные Наблюдения, которые могут излучать ценности в любой момент. Они объединяются для создания Observable<ProcessFileEvent>.

Observable<Integer>  selectedFileId= ...
Observable<MouseClick> buttonClick = ...

Observable<ProcessFileEvent> `processFileEvent` = Observable.combineLatest(selectedFileId, buttonClick, (s,b) -> {
    //create ProcessFileEvent here
});

Проблема в том, что я хочу, чтобы processFileEvent испускал, когда buttonClick испускает что-то, а не selectedFileId. Это определенно не то поведение, которое пользователь ожидает, когда вводится идентификатор файла, и он запускает ProcessFileEvent. Как объединить, но только испускать, когда испускает buttonClick?

Ответ 1

Используйте .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())

Ответ 2

Используйте withLatestFrom:

Observable<Integer>  selectedFileId= ...
Observable<MouseClick> buttonClick = ...

Observable<ProcessFileEvent> processFileEvent = buttonClick.withLatestFrom(selectedFieldId, (b,s) -> {
    //create ProcessFileEvent here
});

Он испускается только при выходе первого Observable buttonClick.

Ответ 3

Вы можете использовать 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 - правильная последовательность.