onNext()永远不会在PublishSubject

时间:2017-08-05 02:09:11

标签: rx-java rx-kotlin publishsubject

我正在尝试构建一个在一段时间内计算某些事件的演示者,仅在第一次加载时显示加载,并在完成后更新ui。因为可以通过多种方式(例如用户首选项)更新事件,所以我需要能够告诉演示者事件已更新并且必须再次刷新事件。这就是我现在所拥有的:

                      subject
                            .map<List<UpcomingRowViewModel>> {
                                provider.calculateEventsBetween(TimePeriod.aYearFrom(firstDay))
                            }
                            .doOnSubscribe {
                                view.showLoading()
                            }
                            .observeOn(resultScheduler)
                            .subscribeOn(workScheduler)
                            .subscribe { upcomingRowViewModels ->
                                view.display(upcomingRowViewModels)
                            }
                      subject.onNext(TRIGGER)

主题是Int的PublishSubject。我在订阅后立即执行onNext(),因为我希望在订阅数据后立即刷新数据。

上面的代码在我的单元测试中起作用,并且只有当我在连接了调试器设备上运行它时。如果我只是运行它(没有任何调试器),它会到达view.showLoading()部分,但永远不会到达provider.calculateEventsBetween(TimePeriod.aYearFrom(firstDay),因此UI会因加载而“卡住”。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

您没有看到被叫消费者的可能原因是.subscribeOn(workScheduler)。通过将此应用于Subject,这本身没有实际用途,因为在订阅Subject时没有订阅副作用,您将订阅延迟到Subject就足够了onNext电话会在那一刻找不到任何观察员。

你可能想要的是这样的:

subject
    .observeOn(resultScheduler)             // <--------------- (1)
    .doOnNext {
        view.showLoading()
    }
    .observeOn(workScheduler)               // <--------------- (2)
    .map<List<UpcomingRowViewModel>> {
        provider.calculateEventsBetween(
            TimePeriod.aYearFrom(firstDay))
    }
    .observeOn(resultScheduler)             // <--------------- (3)
    .subscribe { upcomingRowViewModels ->
        view.display(upcomingRowViewModels)
    }
subject.onNext(TRIGGER)

而不是执行一次的doOnSubscribe,(1)确保当有工作要做时,主题的onNext发射将触发主线程上的加载指示符(假设resultScheduler为AndroidSchedulers.mainThread在非测试中)。然后你想要从主线程执行映射,从而(2)将项目移动到后台线程。映射发生后,结果项目将再次移动到主线程上(3),您的视图可以显示它。