RxJava 2.x: Should I use Flowable or Single/Completable?

[亡魂溺海] 提交于 2019-11-28 17:49:51
npace

Backpressure is what you get when a source Observable is emitting items faster than a Subscriber can consume them. It's most often a concern with hot observables, not cold ones like your network requests.

I think you should use Completable instead of Observable<Void> in your saveUser method, and use Single for all places where you follow a request/response or input/output pattern. Observable should be used when you actually want a continuous stream of events.

Backpressure occurs when an Observable is emitting items more rapidly than an operator or subscriber can consume them.

Knowing that, Backpressure is not an issue in your case as your Observable will emit only one item so Flowable is not a good candidate.

So the real question is whether to use Completable or Observable for saveUser and Single or Observable for findUser and here as only one result is expected (success or failure) for the sake of simplicity and clarity of your API, you should definitively use Completable/Single otherwise it will be hard to understand that only one value will be emitted which could be misleading to your API users.

lmarx

Cardinality is one way of understanding the differences between Completable, Maybe and Single:

  • A Maybe<T> is just an Observable with cardinality 0 or 1 i.e. it represents a result which can either be present or not.
  • A Single<T> is an Observable that always returns a result i.e. a cardinality of 1.
  • A Completable can be interpreted sort of as a Observable<Void> i.e. a cardinality of 0.

So in your case you can change the signature of the repository in this way:

Completable saveUser(...);

Single<User> findUser(...);

(I didn't mention Flowables which are like Observables with backpressure).

As I understand, you should use Single: when you are pretty sure that you are going to get an item, otherwise you would get an error. Eg: GET - card/:id

Maybe: is the correct solution if you are no so sure if you will get an item. Eg: GET - card?license-plate=xvar3

Completable: when you only want to know if the action was made. Eg: PUT or DETELE

Observable: when the quantity of items is not so large.

Flowable: when you don't konw the quantity of items that you will get.

Hmm...

I think the question isn't trivial one while, you have face more complex situation.

Eg. Save user (REST) > Save user (SQLlite)

You may want to chain Rx streams into one.

So either you declare

1.

Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

and then use some of: flatMap, contactMap, switchMap

2.

... or I think may be more preferable to not confuse class responsibility (you may use the same code in many places)

Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

RestService.saveUser(...)
.toFlowable() // Transform into Flowable 
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )

3.

By the way I suggest to not use Completable in case if you want to have nice error handling. You may easily wrap Retrofit.Response<Body> in Single or Flowable to take advantage of the code response from server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!