2017-08-05 114 views
0

我试图构建一个演示者,该演示者在一段时间内计算一些事件,仅在第一次加载时显示加载,并在完成时更新UI。由于事件可以通过多种方式更新(例如用户首选项),因此我需要能够告诉演示者事件已更新,并且必须再次刷新它们。以下是我现在所拥有的:onNext()永远不会在PublishSubject上调用

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

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

上面的代码在我的单元测试中可以创造奇迹,并且只有当我在调试器附带的调试器上运行设备时也是如此。如果我只是运行它(没有任何调试器),它会到达view.showLoading()部分,但不会是provider.calculateEventsBetween(TimePeriod.aYearFrom(firstDay),因此UI会因加载而“卡住”。

任何想法?

回答

2

您未看到消费者所称的可能原因是.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)处您的视图可以显示它。

+0

这样做的窍门!非常感谢你的回复。这在我的脑海里清除了很多哦API的工作原理,因为我错了! –

相关问题