rxJava2 在复杂的流中组合单个、可能、可兼容

2022-09-04 03:49:34

我对新的RxJava感到非常兴奋,例如:,,,,这使您的接口类更干净,并防止在创建“Source”期间出现很多错误(例如,忘记调用SourcesSingleMaybeCompletableonComplete())

但它需要大量的样板文件才能将它们组合成一个复杂的流。

例如,我们有加载和缓存数据的常见Android情况。让我们假设我们有2个来源,我们想把它结合起来:apicache

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());

它不会编译,因为没有重载MaybeMaybe.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();

因此,我看不到任何方法可以在不进行许多转换的情况下使用新源,这些转换会增加代码噪声并创建大量额外的对象。

由于这样的问题,我不能使用,并继续在任何地方使用。SingleMaybeCompletableObservable

所以我的问题是:

  • 组合 、 、 的最佳做法是什么?SingleMaybeCompletable

  • 为什么这些源没有过载以使梳理更容易。

  • 为什么这些源没有共同的祖先,并将其用作
    参数和其他方法?switchIfEmpty


附言有谁知道为什么这些类没有任何共同的层次结构?
从我的角度来看,如果一些代码可以工作,例如使用它也可以正常工作 和 ?CompletableSingleMaybe


答案 1

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 团队通过向 、 、 添加额外的重载,简化了将它们组合在一起的过程,从而做得很好。MaybeSingleObservable

至于 2.1.16 版,我们有以下方法可以组合 和:MaybeSingleCompletable

可能: , , ,flatMapSingleElement(Single):MaybeflatMapSingle(Single):SingleswitchIfEmpty(Single):MaybeflatMapCompletable(Completable):Completable

单人: ,flatMapMaybe(Maybe):MaybeflatMapCompletable(Completable):Completable

可兼容: ,andThen(Single):SingleandThen(Maybe):Maybe


答案 2

我知道这个问题已经很老了,但是,它似乎还没有被接受的答案。

从 RxJava 2.1.4 开始,他们最终添加了:

public final Single<T> switchIfEmpty(SingleSource<? extends T> other)

因此,您可以将链简化为:

cache.switchIfEmpty(api)

如果您拥有最新版本的RxJava,这应该是这种情况的首选方式。请注意,该方法已添加注释,因此将来可能会再次更改。@Experimental


推荐