新しいRxJava Sources
のような、Single
、Maybe
、Completable
を使用すると、インターフェイスクラスがよりクリーンになり、「ソース」の作成時の多くのミスを防ぐことができます(たとえば、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();
_
それを組み合わせるもう1つの可能な方法も、バージョンの変換が必要です。
_final Single<Integer> result = Observable.concat(
cache.loadFromCache().toObservable(),
api.loadFromNetwork().toObservable()
).firstOrError();
_
したがって、コードノイズを追加し、多くの追加オブジェクトを作成する多くの変換なしに、新しいソースを使用する方法はありません。
そのような問題のため、Single
、Maybe
、Completable
を使用できず、どこでもObservable
を引き続き使用できません。
だから私の質問は:
Single
、Maybe
、Completable
を組み合わせる際のベストプラクティスは何ですか。
コーミングを容易にするためにこれらのソースにオーバーロードがないのはなぜですか。
これらのソースに共通の祖先がなく、それを次のように使用する理由switchIfEmpty
およびその他のメソッドのパラメータ?
PSこれらのクラスに共通の階層がない理由を誰かが知っていますか?
たとえば、Completable
で動作するコードがある場合、Single
およびMaybe
でも正常に動作しますか?
RxJava 2.1.4 2017年9月22日にリリースされ、必要なオーバーロード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.16Maybe
、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);
}
});
私はそれをテストしていませんが、可能な解決策になる可能性があると思います(最善かどうかはわかりません)。