我是rxJava的新手,我自己尝试的东西。如果我做得对,我想得到一些建议。
用例:在我的应用程序首次运行时,成功登录后,我必须下载并在本地数据库中保存几个要运行的应用程序的词典。用户必须等到下载过程结束。
当前解决方案:我正在使用rxjava适配器进行改造2以获取数据。我使用zip operator将所有Observable捆绑成一个。完成所有下载后,回调触发并保存到数据库中。
没有比一些代码更好的了解:
Observable<List<OrderType>> orderTypesObservable = backendService.getOrderTypes();
Observable<List<OrderStatus>> orderStatusObservable = mockBackendService.getOrderStatuses();
Observable<List<Priority>> prioritiesObservable = backendService.getPriorities();
return Observable.zip(orderTypesObservable,
orderStatusObservable,
prioritiesObservable,
(orderTypes, orderStatuses, priorities) -> {
orderTypeDao.deleteAll();
orderTypeDao.insertInTx(orderTypes);
orderStatusDao.deleteAll();
orderStatusDao.insertInTx(orderStatuses);
priorityDao.deleteAll();
priorityDao.insertInTx(priorities);
return null;
});
问题:
我应该使用拉链操作符还是更适合我的原因?
这样做似乎有点乱。这只是代码的一部分,我目前有12个字典要加载。有没有办法重构它?
我想在完成下载后立即插入单个字典数据,并在下载失败时使用重试机制。我怎样才能做到这一点?
答案 0 :(得分:2)
我认为在你的情况下最好使用Completable,因为你只关心任务完成。
l
如果您需要连续执行 - 请使用Completable getAndStoreOrderTypes = backendService.getOrderTypes()
.doOnNext(types -> *store to db*)
.toCompletable();
Completable getAndStoreOrderStatuses = backendService.getOrderStatuses()
.doOnNext(statuses -> *store to db*)
.toCompletable();
Completable getAndStoreOrderPriorities = backendService.getOrderPriorities()
.doOnNext(priorities -> *store to db*)
.toCompletable();
return Completable.merge(getAndStoreOrderTypes,
getAndStoreOrderStatuses,
getAndStoreOrderPriorities);
代替Completable.concat()
如果下载失败,则重试机制
使用方便的merge()
运算符
答案 1 :(得分:1)
将null值对象抛入Rx Stream并不好(在zip中返回null,这很糟糕)。 尽量不这样做。
在您的情况下,您有1个api调用和2个操作来将响应保存到数据库中,因此您可以使用flatMap创建链。
看起来像:
backendService.getOrderTypes()
.doOnNext(savingToDatabaseLogic)
.flatMap(data -> mockBackendService.getOrderStatuses())
.doOnNext(...)
.flatMap(data -> backendService.getPriorities())
.doOnNext(...)
如果你想对错误情况作出反应,特别是observable,你可以添加onErrorResumeNext(exception-&gt; Observable.empty()),即使发生了什么事情,链也会继续
此外,您可以创建类似BaseDao的东西,它可以保存任何Dao对象。