2017-07-06 115 views
2

我有一個函數,它應該返回一個BehaviorSubject。主題是想回的最新版本Profile如何創建訂閱observable的BehaviorSubject?

(用戶)Profile僅僅是包含三個成員引用一個POJO:
- 一個User
- 即用戶MeasurementList
- 和Deadline

其中兩個屬性是通過改進調用獲得的,其中一個屬性已經存放在一個類變量中。

每當可觀察者發出新的measurement listdeadline時,BehaviorSubject應發出一個新的更新的配置文件。

這裏是什麼應該發生 enter image description here

這是我迄今爲止

public BehaviorSubject<Profile> observeProfile() { 

     if (profileBS == null) { 

      profileBS = BehaviorSubject.create(); 

      Observable o = Observable.combineLatest(
        Observable.just(userAccount), 
        observeMeasurements(), 
        observeDeadline(), 
        Profile::new 
      ); 


      profileBS.subscribeTo(o); //subscribeTo does not exist, but this is what I am trying to figure out how to do. 

     } 
     return profileBS; 
    } 

誰能幫助我正確地創建這個BehaviorSubject(希望有用)圖?

謝謝。

回答

2

Subject實現Observer接口,這樣你可以做以下

public BehaviorSubject<Profile> observeProfile() { 

     if (profileBS == null) { 

      profileBS = BehaviorSubject.create(); 

      Observable o = Observable.combineLatest(
        Observable.just(userAccount), 
        observeMeasurements(), 
        observeDeadline(), 
        Profile::new 
      ); 

      // Note the following returns a subscription. If you want to prevent leaks you need some way of unsubscribing. 
      o.subscribe(profileBS); 

     } 
     return profileBS; 
} 

請注意,您應該拿出處理所產生的認購方式。

+0

謝謝。答案很簡單,但最初對我來說似乎有些違反直覺。 – Stephen

+0

@Stephen這個答案可以工作,但有一定的條件。正如我在我的回答中所說的,你太早訂閱你的上游。所以你的下游將失去它的事件。 –

+0

@PhoenixWang我現在正在閱讀你的答案。我會看看。我現在必須馬上開始工作,但稍後會跟進。感謝您的高舉。 – Stephen

0

我想我和你面臨同樣的問題。我想在提出答案之前先講述一些歷史。 所以我覺得很多人都看到了傑克華頓在Devoxx上的講話:The State of Managing State with RxJava

所以他想出了一個基於一些變形金剛的建築。但問題是,即使這些Transformer實例在ViewObservables之外生存。他們每次使用ViewObservable時都會創建新的Observable。這是因爲運營商的概念。

因此,一個常見的解決方案是使用主題作爲您的問題做的網關。但新問題是你太早訂閱你的信息來源。

訂閱操作應該在subscribeActual()中完成,這將由您的下游的subscribe()方法觸發。但是你在中間訂閱你的上游。你失去了你的事件。 通過解決這個問題我很困難,但從未找到解決方案。

但最近由於Davik的回答是:RxJava - .doAfterSubscribe()? 我想出了這樣的事情:

public BehaviorSubject<Profile> observeProfile() { 
    public Observable resultObservable; 
    if (profileBS == null) { 

     profileBS = BehaviorSubject.create(); 
     //this source observable should save as a field as well 
     o = Observable.combineLatest(
       Observable.just(userAccount), 
       observeMeasurements(), 
       observeDeadline(), 
       Profile::new 
     ); 
     //return this observable instead of your subject 
     resultObservable = profileBS.mergeWith(
      Observable.empty() 
         .doOnComplete(() -> { 
          o.subscribe(profileBS); 
         })) 
    } return resultObservable; 
} 

的訣竅是。您使用此批准程序來創建像doAfterSubscribe這樣的運營商。所以只有下游已經訂閱你的主題。您的主題將訂閱您的原始上游來源。

希望這可以幫助。併爲我的英語不好而感到抱歉。

+0

'susbcribeActual'只有rxJava2我認爲。 – JohnWowUs

+0

@JohnWowUs是的,但概念是相同的。通過觸發'subscribe()'方法,Obseravble應該被認爲是懶惰地初始化的。但是在這個方法中,Subject不管你的「主」訂閱是否訂閱你的主題,都訂閱原始源,以便從源接收事件。這就是你失去活動的原因。 –