RxJava:如何等待所有订阅完成?

时间:2016-11-13 20:22:45

标签: android rx-java

我是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个字典要加载。有没有办法重构它?

我想在完成下载后立即插入单个字典数据,并在下载失败时使用重试机制。我怎样才能做到这一点?

2 个答案:

答案 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对象。