我对新的RxJava Sources
感到非常兴奋,例如:Single
,Maybe
,Completable
,这使您的界面类更清晰,并防止在此期间出现大量错误创建您的“来源”(例如忘记致电onComplete()
)
但它需要大量的样板才能将它们组合成一个复杂的流。
E.g。我们有常见的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
。
为什么这些来源没有重载来简化梳理。
为什么这些来源没有共同的祖先并将其用作
参数switchIfEmpty
和其他方法?
P.S。有人知道为什么这些类没有任何共同的层次结构吗?
从我的角度来看,如果某些代码可以与Completable
一起使用,它也可以与Single
和Maybe
一起使用吗?
答案 0 :(得分:4)
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
答案 1 :(得分:2)
我知道这个问题已经很老了,但似乎尚未被接受。
从RxJava 2.1.4开始,他们终于添加了:
public final Single<T> switchIfEmpty(SingleSource<? extends T> other)
因此您可以将连锁简化为:
cache.switchIfEmpty(api)
如果您具有最新版本的RxJava,则应该是这种情况的首选方法。请注意,该方法使用@Experimental
进行了注释,因此将来可能会再次更改。
答案 2 :(得分:0)
也许我不是一个全面的答案,但我试着回答你的具体用例:
我认为你的组合任务的目的是从缓存中获取数据,如果结果是空的,你想调用远程api:
.foo {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
margin: -50px 0 0 -50px;
background: lightblue; //not necessary of course
}
我没有测试过,但我认为可能是一种可能的解决方案(不确定是否最好)。