[英]rxJava2 Combining Single, Maybe, Completable in complex Streams
我對新的RxJava Sources
非常興奮,例如: Single
, Maybe
, Completable
,這使得你的接口類更清晰,並防止在創建你的'Source'時出現很多錯誤(例如忘記調用onComplete()
)
但它需要大量的樣板才能將它們組合成一個復雜的流。
例如,我們有加載和緩存數據的常見Android情況。 假設我們有2個源api
和cache
,我們希望將它組合起來:
public interface Api {
Single<Integer> loadFromNetwork();
}
public interface Cache {
Maybe<Integer> loadFromCache(); //maybe because cache might not have item.
}
讓我們試着把它結合起來:
final Single<Integer> result = cache.loadFromCache()
.switchIfEmpty(api.loadFromNetwork());
它不會編譯,因為Maybe
沒有重載Maybe.switchIfEmpty(Single):Single
所以我們必須轉換一切:
final Single<Integer> result = cache.loadFromCache()
.switchIfEmpty(api.loadFromNetwork().toMaybe())
.toSingle();
組合它的另一種可能方法還需要сonversion:
final Single<Integer> result = Observable.concat(
cache.loadFromCache().toObservable(),
api.loadFromNetwork().toObservable()
).firstOrError();
所以我沒有看到任何方法來使用新的源代碼而沒有很多轉換會增加代碼噪聲並創建大量額外的對象。
由於這些問題,我無法使用Single
, Maybe
, Completable
並繼續使用Observable
。
所以我的問題是:
結合Single
, Maybe
, Completable
的最佳實踐是什么?
為什么這些Source沒有重載來簡化梳理。
為什么這些來源沒有共同的祖先並將其用作
switchIfEmpty
參數和其他方法?
PS有誰知道為什么這些類沒有任何共同的層次結構?
從我的角度來看,如果某些代碼可以用例如Completable
那么Single
和Maybe
也能正常工作嗎?
2017年9月22日發布的RxJava 2.1.4增加了所需的重載Maybe.switchIfEmpty(Single):Single
。
因此,如果我們想要合並以下類:
public interface Api {
Single<Integer> loadFromNetwork();
}
public interface Cache {
Maybe<Integer> loadFromCache(); //maybe because cache might not have item.
}
我們終於可以做到:
final Single<Integer> result = cache.loadFromCache()
.switchIfEmpty(api.loadFromNetwork());
Rx團隊通過為Maybe
, Single
, Observable
添加額外的重載來完成這項工作,簡化了將它們組合在一起的過程。
至於版本2.1.16,我們有以下方法用於組合Maybe
, Single
和Completable
:
也許 : flatMapSingleElement(Single):Maybe
, flatMapSingle(Single):Single
, switchIfEmpty(Single):Maybe
, flatMapCompletable(Completable):Completable
單一 : flatMapMaybe(Maybe):Maybe
, flatMapCompletable(Completable):Completable
可完成 : andThen(Single):Single
, andThen(Maybe):Maybe
我知道這個問題已經過時了,但似乎尚未接受答案。
從RxJava 2.1.4開始,他們最終添加:
public final Single<T> switchIfEmpty(SingleSource<? extends T> other)
所以你可以簡化你的鏈:
cache.switchIfEmpty(api)
如果你有最新版本的RxJava,這應該是這種情況的首選方式。 請注意,該方法是使用@Experimental
注釋的,因此將來可能會再次更改。
也許我不是一個全面的答案,但我試着回答你的具體用例:
我認為你的組合任務的目的是從緩存中獲取數據,如果結果是空的,你想調用遠程api:
final Single<List<Integer>> single = api.call();
Maybe<List<Integer>> maybe = disk.call();
Single <List<Integer>> composedSingle = maybe.flatMapSingle(new Function<List<Integer>, SingleSource<?>>() {
@Override
public SingleSource<?> apply(List<Integer> integers) throws Exception {
if(integers.isEmpty()) return single;
else return Single.just(integers);
}
});
我沒有測試它,但我認為可能是一個可能的解決方案(不確定是否最好)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.