2017-08-05 165 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的工作原理,因爲我錯了! –

相關問題