繁体   English   中英

rxJava2在复杂流中组合Single,Maybe,Completable

[英]rxJava2 Combining Single, Maybe, Completable in complex Streams

我对新的RxJava Sources非常兴奋,例如: SingleMaybeCompletable ,这使得你的接口类更清晰,并防止在创建你的'Source'时出现很多错误(例如忘记调用onComplete()

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

例如,我们有加载和缓存数据的常见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());

它不会编译,因为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();

所以我没有看到任何方法来使用新的源代码而没有很多转换会增加代码噪声并创建大量额外的对象。

由于这些问题,我无法使用SingleMaybeCompletable并继续使用Observable

所以我的问题是:

  • 结合SingleMaybeCompletable的最佳实践是什么?

  • 为什么这些Source没有重载来简化梳理。

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


PS有谁知道为什么这些类没有任何共同的层次结构?
从我的角度来看,如果某些代码可以用例如Completable那么SingleMaybe也能正常工作吗?

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

我知道这个问题已经过时了,但似乎尚未接受答案。

从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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM