java RxJava 2.x:我应该使用 Flowable 还是 Single/Completable?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42525623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:42:15  来源:igfitidea点击:

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

javaandroidreactive-programmingrx-java2

提问by Pablo Alonso González

I'm developing an Android app using Clean Architecture and I'm migrating it to RxJava 2.x. I have to make some network requests to a soap service, so I defined the api interface in the domain module:

我正在使用 Clean Architecture 开发一个 Android 应用程序,并将它迁移到 RxJava 2.x。我必须向soap服务发出一些网络请求,所以我在域模块中定义了api接口:

public interface SiginterApi {
    Observable<User> login(String user, String password);
    ...
    Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}

I've read that a network request should be made with "Flowable", because of the backpressure management since it's a 'cold observable'. On the other hand, I know the result of the request will be success (with the response) or error, so I don't know if I should use Flowableor Singleor even Observable.

我已经读过网络请求应该使用“ Flowable”,因为背压管理,因为它是一个“冷可观察”。在另一方面,我知道请求的结果将是成功的(与响应)或错误,所以我不知道我是否应该使用FlowableSingle甚至Observable

Furthermore, I have a database accesses like this:

此外,我有一个这样的数据库访问:

public interface UserRepository extends Repository {
    Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
    ...
    Observable<User> findUser(String username, String hashedPassword);
}

I don't know if I should use Completable/Flowable/Observablein saveUsermethod and Single/Flowable/Observablein findUsermethod.

我不知道我是否应该使用Completable/ Flowable/ ObservableinsaveUser方法和Single/ Flowable/ ObservableinfindUser方法。

采纳答案by npace

Backpressure is what you get when a source Observableis emitting items faster than a Subscribercan consume them. It's most often a concern with hotobservables, not coldones like your network requests.

背压是当源Observable发射物品的速度比Subscriber消耗它们的速度快时你得到的。最常见的问题是observables,而不是像您的网络请求这样的observables 。

I think you should use Completableinstead of Observable<Void>in your saveUsermethod, and use Singlefor all places where you follow a request/response or input/output pattern. Observableshould be used when you actually want a continuous stream of events.

我认为你应该在你的方法中使用Completable而不是使用,并用于所有遵循请求/响应或输入/输出模式的地方。当您确实需要连续的事件流时,应该使用它。Observable<Void>saveUserSingleObservable

回答by Nicolas Filotto

Backpressureoccurs when an Observableis emitting items more rapidly than an operator or subscriber can consume them.

发送Observable项目的速度超过运营商或订阅者可以使用它们的速度就会发生背压

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

知道这一点,背压在您的情况下不是问题,因为您Observable只会发出一个项目,因此Flowable不是一个好的候选人。

So the real question is whether to use Completableor Observablefor saveUserand Singleor Observablefor findUserand 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/Singleotherwise it will be hard to understand that only one value will be emitted which could be misleading to your API users.

所以真正的问题是是否使用Completableor Observablefor saveUserand Singleor Observablefor findUserand here 因为为了 API 的简单性和清晰度,只预期一个结果(成功或失败),您应该明确使用Completable/Single否则将很难理解只会发出一个值,这可能会误导您的 API 用户。

回答by lmarx

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

基数是理解CompletableMaybeSingle之间差异的一种方式:

  • 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 Completablecan be interpreted sort of as a Observable<Void>i.e. a cardinality of 0.
  • AMaybe<T>只是一个基数为 0 或 1 的 Observable,即它代表一个结果,可以存在也可以不存在。
  • ASingle<T>是一个 Observable,它总是返回一个结果,即基数为 1。
  • ACompletable可以解释为 a,Observable<Void>即基数为 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).

(我没有提到Flowables 就像Observables 带有背压)。

回答by dmarquina

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

据我了解,您应该使用 Single: 当您非常确定您将获得一个项目时,否则您会收到错误消息。例如: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

也许:如果您不确定是否会收到物品,这是正确的解决方案。例如:GET - card?license-plate=xvar3

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

Completable:当您只想知道操作是否已完成时。例如:PUT 或 DETELE

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

Observable:当物品的数量不是很大时。

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

Flowable:当你不知道你会得到多少物品时。

回答by AouledIssa

  • If your Observable(service) is emitting items at a faster rate than your observer (client) then you should use Flowableto benefit from the back pressure mechanism. Hot Observable
  • If your service will emit once per request and on demand data (most case of API) then it should be treated as a cold observable. In this case go for Singleor Maybe. The difference is that if you want to handle the case where the service send no response or error in this case Singleis better to use by leveraging the onError()callback. If you don't case if your service will fail or succeed and you don't mind an empty emission and go for Maybe.
  • 99% of database WRITErequests return nothing (only if you want to ensure your data by returning a boolean) in this use case I would use Completableto execute the action and call onComplete()at the end.
  • 如果您的Observable(服务)以比您的观察者(客户端)更快的速度发出项目,那么您应该使用Flowable背压机制来受益。热观察
  • 如果您的服务将根据请求和按需数据(大多数情况下的 API)发出一次,则应将其视为冷可观察对象。在这种情况下,请选择SingleMaybe。不同的是,如果你想处理这种情况下服务不发送响应或错误的情况Single,最好利用onError()回调来使用。如果你不担心你的服务会失败还是成功,并且你不介意空洞的发射,然后去Maybe.
  • WRITE在这个用例中,99% 的数据库请求不返回任何内容(仅当您想通过返回布尔值来确保您的数据时),我将Completable用来执行操作并onComplete()在最后调用。

回答by murt

Hmm...

唔...

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

我认为当您面临更复杂的情况时,这个问题并不是一个微不足道的问题。

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

例如。 保存用户 (REST) > 保存用户 (SQLlite)

You may want to chainRx streams into one.

你可能想的Rx流为一体。

So either you declare

所以要么你声明

1.

1.

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

and then use some of: flatMap, concatMap, switchMap

然后使用其中的一些: flatMap, concatMap, switchMap

2.

2.

... or I think maybe 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.

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 Singleor Flowableto take advantage of the code response from server

顺便说一句,我建议不要使用 Completable 以防万一你想要很好的错误处理。你可以很容易地包裹Retrofit.Response<Body>SingleFlowable采取从服务器代码响应的优势