簡體   English   中英

如何在RxJava中具有多個可分組觀察的訂戶?

[英]How To Have Multiple Subscribers To A Grouped Observable in RxJava?

這使用的是RxJava版本0.19.6

在groupBy操作之外,可以創建以下代碼描述的管道,例如,基於某些條件從Observable中選擇一條記錄,或選擇滿足某些替代條件的第一條記錄:

Observable<Long> observable = Observable.interval(1, TimeUnit.MILLISECONDS).take(10);
Observable<Long> filter1 = observable.filter(new Func1<Long, Boolean>() {
    @Override
    public Boolean call(Long aLong) {
        return 5 == aLong % 5;
    }
});
Observable<Long> filter2 = observable.filter(new Func1<Long, Boolean>() {
    @Override
    public Boolean call(Long aLong) {
        return 2 == aLong % 5;
    }
});
BlockingObservable.from(Observable.concat(filter1, filter2).first()).forEach(new Action1<Long>() {
    @Override
    public void call(Long aLong) {
        System.out.println(aLong);
    }
});

...不幸的是,由於對GroupedObservable的限制,似乎無法在分組上下文中運行相同類型的過程:

BlockingObservable.from(observable.groupBy(new Func1<Long, Long>() {
    @Override
    public Long call(Long aLong) {
        return aLong % 5;
    }
}).flatMap(new Func1<GroupedObservable<Long, Long>, Observable<Long>>() {
    @Override
    public Observable<Long> call(GroupedObservable<Long, Long> in) {
        Observable<Long> filter1 = in.filter(new Func1<Long, Boolean>() {
            @Override
            public Boolean call(Long aLong) {
                return 5 == aLong % 5;
            }
        });
        Observable<Long> filter2 = in.filter(new Func1<Long, Boolean>() {
            @Override
            public Boolean call(Long aLong) {
                return 2 == aLong % 5;
            }
        });
        return Observable.concat(filter1, filter2).first();
    }
})).forEach(new Action1<Long>() {
    @Override
    public void call(Long aLong) {
        System.out.println(aLong);
    }
});

...導致多個訂閱者異常(線程“ main”中的異常java.lang.IllegalStateException:僅允許一個訂閱者!)。

我是否缺少解決此問題的明顯方法? 在這種情況下,我嘗試使用ConnectableObservables來顯示單個訂戶的外觀,但是這些嘗試同樣也是失敗的(肯定是由於我的無知)。


與此相關的是,groupByUntil似乎也為您提供了對GroupedObservable的引用,如果我實際上試圖使用它來確定何時關閉窗口,那么這也使我感到類似的麻煩,抱怨多個訂閱者。 再次重申,我確信自己會忽略一些明顯的事情,因為API顯然希望人們使用GroupedObservable!

您可能可以在GroupedObservable上使用.cache()。

final Observable<Long> inCached = in.cache();

然后在您的過濾器中使用結果Observable。

Observable<Long> filter1 = inCached.filter(new Func1<Long, Boolean>() {
        @Override
        public Boolean call(Long aLong) {
            return 5 == aLong % 5;
        }
    });

這樣,每個訂戶將看到相同的項目,但是GroupedObservable只有一個訂戶。

您可以將過濾器組合成單個過濾器,如下所示:

Observable<Long> observable = Observable.interval(1, TimeUnit.MILLISECONDS).take(10);
BlockingObservable.from(observable.groupBy(new Func1<Long, Long>() {
    @Override
    public Long call(Long aLong) {
        return aLong % 5;
    }
}).flatMap(new Func1<GroupedObservable<Long, Long>, Observable<Long>>() {
    @Override
    public Observable<Long> call(GroupedObservable<Long, Long> in) {
        Observable<Long> filter = in.filter(new Func1<Long, Boolean>() {
            @Override
            public Boolean call(Long aLong) {
                return 2 == aLong % 5 || 4 == aLong % 5;
            }
        });
        return filter;
    }
})).forEach(new Action1<Long>() {
    @Override
    public void call(Long aLong) {
        System.out.println(aLong);
    }
});

您是否嘗試過升級rxJava版本?

https://github.com/ReactiveX/RxJava/issues/957

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM