RxJava2 Single join possibly completed in complex threads

I am very concerned about the new RxJava Sources , such as: Single , Maybe , Completable , which make your interface classes cleaner and prevent many errors when creating your "source" (for example, forgetting to call onComplete() )

But this requires a lot of templates to combine them into a complex stream.

eg. we have a general situation with Android for loading and caching data. Suppose we have 2 api and cache sources, and we would like to combine them:

 public interface Api { Single<Integer> loadFromNetwork(); } public interface Cache { Maybe<Integer> loadFromCache(); //maybe because cache might not have item. } 

try combining it:

 final Single<Integer> result = cache.loadFromCache() .switchIfEmpty(api.loadFromNetwork()); 

it will not compile because Maybe has no overload. Maybe.switchIfEmpty(Single):Single

so we need to convert everything:

 final Single<Integer> result = cache.loadFromCache() .switchIfEmpty(api.loadFromNetwork().toMaybe()) .toSingle(); 

Another possible way to combine it also requires conversion:

 final Single<Integer> result = Observable.concat( cache.loadFromCache().toObservable(), api.loadFromNetwork().toObservable() ).firstOrError(); 

Therefore, I do not see the possibility of using new sources without many conversions that add code noise and create many additional objects.

Due to such problems, I cannot use Single , Maybe , Completable and continue to use Observable everywhere.

So my question is:

  • What are the best union methods for Single , Maybe , Completable .

  • Why these sources do not have overloads to facilitate combing.

  • Why these sources do not have a common ancestor and use it as
    switchIfEmpty parameter and other methods?


PS Does anyone know why these classes do not have a common hierarchy?
From my point of view, if some code can work, for example, using Completable , it also works fine with Single and Maybe ?

+5
source share
1 answer

I may not be the complete answer, but I'm trying to answer your specific use case:

I think the goal of your combining task is to extract data from the cache, if the result is empty, you want to call the remote 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); } }); 

I have not tested it, but I think it might be a possible solution (not sure if the best).

0
source

Source: https://habr.com/ru/post/1270229/


All Articles