RxJava 2.x:我应该使用 Flowable 还是 Single/Completable?
RxJava 2.x: Should I use Flowable or Single/Completable?
我正在使用 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);
}
我读到应该使用“Flowable
”发出网络请求,因为背压管理是 'cold observable'。另一方面,我知道请求的结果将是成功(有响应)或错误,所以我不知道我是否应该使用 Flowable
或 Single
甚至 Observable
.
此外,我有一个这样的数据库访问:
public interface UserRepository extends Repository {
Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
...
Observable<User> findUser(String username, String hashedPassword);
}
我不知道是否应该在 saveUser
方法和 Single
/Flowable
中使用 Completable
/Flowable
/Observable
/Observable
在 findUser
方法中。
背压是当源 Observable
发射物品的速度快于 Subscriber
消耗它们时所得到的。 hot observables 通常是一个问题,而不是像你的网络请求那样的 cold observables。
我认为您应该在 saveUser
方法中使用 Completable
而不是 Observable<Void>
,并在所有遵循 request/response 的地方使用 Single
或 input/output 模式。 Observable
应该在您真正想要连续的事件流时使用。
Backpressure 当 一个 Observable
发射物品的速度快于运营商或订阅者消耗它们的速度时发生 。
知道了,Backpressure 在你的情况下不是问题,因为你的 Observable
只会发出一个项目,所以 Flowable
不是一个好的候选者。
所以真正的问题是saveUser
是用Completable
还是Observable
,findUser
是用Single
还是Observable
,这里因为为了您的 API 的简单和清晰起见,只有一个结果(成功或失败)是预期的,您应该明确地使用 Completable
/Single
否则很难理解只有将发出一个值,这可能会误导您的 API 用户。
嗯……
我认为这个问题不是微不足道的,因为你面对的是更复杂的情况。
例如。
保存用户 (REST) > 保存用户 (SQLlite)
您可能想要 将 个 Rx 流合并为一个。
所以要么你声明
1.
Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
然后使用一些:flatMap, concatMap, switchMap
2.
... 或者我认为最好不要混淆 class 责任(您可能会在许多地方使用相同的代码)
Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
RestService.saveUser(...)
.toFlowable() // Transform into Flowable
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )
3.
顺便说一句,如果你想要更好的错误处理,我建议不要使用 Completable。您可以轻松地将 Retrofit.Response<Body>
包装在 Single
或 Flowable
中以利用来自服务器
的代码响应
据我了解,您应该使用
单一:当你非常确定你会得到一个项目时,否则你会得到一个错误。
例如:GET - card/:id
也许:如果您不确定是否会得到某件商品,这是正确的解决方案。
例如:GET - card?license-plate=xvar3
可完成:当您只想知道操作是否已执行时。
例如:PUT 或 DETELE
Observable:当物品的数量不是很大的时候。
可流动:当您不知道您将获得的物品数量时。
基数是理解 Completable、Maybe 和 Single 之间差异的一种方式:
- A
Maybe<T>
只是一个基数为 0 或 1 的 Observable,即它表示一个可以存在或不存在的结果。
- A
Single<T>
是一个总是 returns 结果的 Observable,即基数为 1.
- A
Completable
可以解释为 Observable<Void>
即基数 0.
因此在您的情况下,您可以通过这种方式更改存储库的签名:
Completable saveUser(...);
Single<User> findUser(...);
(我没有提到 Flowable
s 就像 Observable
s 和 backpressure)。
- 如果您的
Observable
(服务)以比您的观察者(客户端)更快的速度发送项目,那么您应该使用 Flowable
以从背压机制中获益。 热门 Observable
- 如果您的服务将针对每个请求和按需数据发出一次(API 的大多数情况),那么它应该被视为冷可观察对象。在这种情况下,选择
Single
或 Maybe
。不同之处在于,如果你想处理服务不发送响应或错误的情况,在这种情况下 Single
最好通过利用 onError()
回调来使用。如果您不考虑您的服务是失败还是成功,并且您不介意空排放并选择 Maybe
.
- 99% 的数据库
WRITE
请求 return 什么都没有(只有当你想通过 returning 一个布尔值来确保你的数据时)在这个用例中我会使用 Completable
执行动作并在最后调用 onComplete()
。
我正在使用 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);
}
我读到应该使用“Flowable
”发出网络请求,因为背压管理是 'cold observable'。另一方面,我知道请求的结果将是成功(有响应)或错误,所以我不知道我是否应该使用 Flowable
或 Single
甚至 Observable
.
此外,我有一个这样的数据库访问:
public interface UserRepository extends Repository {
Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
...
Observable<User> findUser(String username, String hashedPassword);
}
我不知道是否应该在 saveUser
方法和 Single
/Flowable
中使用 Completable
/Flowable
/Observable
/Observable
在 findUser
方法中。
背压是当源 Observable
发射物品的速度快于 Subscriber
消耗它们时所得到的。 hot observables 通常是一个问题,而不是像你的网络请求那样的 cold observables。
我认为您应该在 saveUser
方法中使用 Completable
而不是 Observable<Void>
,并在所有遵循 request/response 的地方使用 Single
或 input/output 模式。 Observable
应该在您真正想要连续的事件流时使用。
Backpressure 当 一个 Observable
发射物品的速度快于运营商或订阅者消耗它们的速度时发生 。
知道了,Backpressure 在你的情况下不是问题,因为你的 Observable
只会发出一个项目,所以 Flowable
不是一个好的候选者。
所以真正的问题是saveUser
是用Completable
还是Observable
,findUser
是用Single
还是Observable
,这里因为为了您的 API 的简单和清晰起见,只有一个结果(成功或失败)是预期的,您应该明确地使用 Completable
/Single
否则很难理解只有将发出一个值,这可能会误导您的 API 用户。
嗯……
我认为这个问题不是微不足道的,因为你面对的是更复杂的情况。
例如。 保存用户 (REST) > 保存用户 (SQLlite)
您可能想要 将 个 Rx 流合并为一个。
所以要么你声明
1.
Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
然后使用一些:flatMap, concatMap, switchMap
2.
... 或者我认为最好不要混淆 class 责任(您可能会在许多地方使用相同的代码)
Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);
RestService.saveUser(...)
.toFlowable() // Transform into Flowable
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )
3.
顺便说一句,如果你想要更好的错误处理,我建议不要使用 Completable。您可以轻松地将 Retrofit.Response<Body>
包装在 Single
或 Flowable
中以利用来自服务器
据我了解,您应该使用 单一:当你非常确定你会得到一个项目时,否则你会得到一个错误。 例如:GET - card/:id
也许:如果您不确定是否会得到某件商品,这是正确的解决方案。 例如:GET - card?license-plate=xvar3
可完成:当您只想知道操作是否已执行时。 例如:PUT 或 DETELE
Observable:当物品的数量不是很大的时候。
可流动:当您不知道您将获得的物品数量时。
基数是理解 Completable、Maybe 和 Single 之间差异的一种方式:
- A
Maybe<T>
只是一个基数为 0 或 1 的 Observable,即它表示一个可以存在或不存在的结果。 - A
Single<T>
是一个总是 returns 结果的 Observable,即基数为 1. - A
Completable
可以解释为Observable<Void>
即基数 0.
因此在您的情况下,您可以通过这种方式更改存储库的签名:
Completable saveUser(...);
Single<User> findUser(...);
(我没有提到 Flowable
s 就像 Observable
s 和 backpressure)。
- 如果您的
Observable
(服务)以比您的观察者(客户端)更快的速度发送项目,那么您应该使用Flowable
以从背压机制中获益。 热门 Observable - 如果您的服务将针对每个请求和按需数据发出一次(API 的大多数情况),那么它应该被视为冷可观察对象。在这种情况下,选择
Single
或Maybe
。不同之处在于,如果你想处理服务不发送响应或错误的情况,在这种情况下Single
最好通过利用onError()
回调来使用。如果您不考虑您的服务是失败还是成功,并且您不介意空排放并选择Maybe
. - 99% 的数据库
WRITE
请求 return 什么都没有(只有当你想通过 returning 一个布尔值来确保你的数据时)在这个用例中我会使用Completable
执行动作并在最后调用onComplete()
。