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
RxJava 2.x: Should I use Flowable or Single/Completable?
提问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 Flowable
or Single
or even Observable
.
我已经读过网络请求应该使用“ Flowable
”,因为背压管理,因为它是一个“冷可观察”。在另一方面,我知道请求的结果将是成功的(与响应)或错误,所以我不知道我是否应该使用Flowable
或Single
甚至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
/Observable
in saveUser
method and Single
/Flowable
/Observable
in findUser
method.
我不知道我是否应该使用Completable
/ Flowable
/ Observable
insaveUser
方法和Single
/ Flowable
/ Observable
infindUser
方法。
采纳答案by 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 hotobservables, not coldones like your network requests.
背压是当源Observable
发射物品的速度比Subscriber
消耗它们的速度快时你得到的。最常见的问题是热observables,而不是像您的网络请求这样的冷observables 。
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.
我认为你应该在你的方法中使用Completable
而不是使用,并用于所有遵循请求/响应或输入/输出模式的地方。当您确实需要连续的事件流时,应该使用它。Observable<Void>
saveUser
Single
Observable
回答by Nicolas Filotto
Backpressureoccurs when an Observable
is 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 Observable
will emit only one item so Flowable
is not a good candidate.
知道这一点,背压在您的情况下不是问题,因为您Observable
只会发出一个项目,因此Flowable
不是一个好的候选人。
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.
所以真正的问题是是否使用Completable
or Observable
for saveUser
and Single
or Observable
for findUser
and here 因为为了 API 的简单性和清晰度,只预期一个结果(成功或失败),您应该明确使用Completable
/Single
否则将很难理解只会发出一个值,这可能会误导您的 API 用户。
回答by lmarx
Cardinality is one way of understanding the differences between Completable, Maybeand Single:
基数是理解Completable、Maybe和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 aObservable<Void>
i.e. a cardinality of 0.
- A
Maybe<T>
只是一个基数为 0 或 1 的 Observable,即它代表一个结果,可以存在也可以不存在。 - A
Single<T>
是一个 Observable,它总是返回一个结果,即基数为 1。 - A
Completable
可以解释为 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 Flowable
s which are like Observable
s with backpressure).
(我没有提到Flowable
s 就像Observable
s 带有背压)。
回答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 useFlowable
to 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
Single
orMaybe
. The difference is that if you want to handle the case where the service send no response or error in this caseSingle
is better to use by leveraging theonError()
callback. If you don't case if your service will fail or succeed and you don't mind an empty emission and go forMaybe
. - 99% of database
WRITE
requests return nothing (only if you want to ensure your data by returning a boolean) in this use case I would useCompletable
to execute the action and callonComplete()
at the end.
- 如果您的
Observable
(服务)以比您的观察者(客户端)更快的速度发出项目,那么您应该使用Flowable
背压机制来受益。热观察 - 如果您的服务将根据请求和按需数据(大多数情况下的 API)发出一次,则应将其视为冷可观察对象。在这种情况下,请选择
Single
或Maybe
。不同的是,如果你想处理这种情况下服务不发送响应或错误的情况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 Single
or Flowable
to take advantage of the code response from server
顺便说一句,我建议不要使用 Completable 以防万一你想要很好的错误处理。你可以很容易地包裹Retrofit.Response<Body>
在Single
或Flowable
采取从服务器代码响应的优势