2016-11-27 69 views
4

我有一個初始化爲網絡調用的類變量。RxJava:如何等待先前訂閱初始化的值?

類似getter的方法負責返回初始化的值,或者等待如果網絡調用尚未返回,則初始化值。

如何用RxJava實現這個?

另一種解決方案是不是等待,我可以簡單地創建一個新的網絡通話的情況下,該值仍然沒有初始化,就像這樣:

private String value; 

public Observable<String> getValue() { 
    if (value != null) { 
     return Observable.just(value); 
    } 

    return getValueRemotely(); 
} 

private Observable<String> getValueRemotely() { 
    ... 
} 

,但我想避免多個網絡電話要做。

有什麼想法?

回答

4

對於AsyncSubject這實際上是一個很好的用例。

private AsyncSubject<String> value = AsyncSubject.create(); 

public Observable<String> getValue() { 
    value.asObservable(); 
} 

而且在getValueRemotely()你必須確保對valueonNext()onComplete()呼叫。

value.onNext(valueString); 
value.onCommpleted(); 

只有當它完成的AsyncSubject觀察到發射一個項目。

+0

不錯,爲我工作,謝謝! – Kain

0

TL; DR - 包裝你的變量爲可觀察:

Observable<String> value = Observable 
    .defer(() -> Observable.just(getValueRemotely())) 
    .cacheWithInitialCapacity(1); 

...然後使用它:

value.subscribe(v -> /*use value received from net*/); 

背景:RxJava是回調爲主。所以,當你想從你的observable中獲得某些東西時,你不會說'return observable.get()' - 相反,你提供了一個回調函數來接收observable的內容。也許。實際上,什麼時候會有內容。

需要一些心智的努力來包圍你的頭。使用RxJava,你很少輸入'return'關鍵字,而是傳遞迴調。開始時可能會感到奇怪,但在某些情況下,回調比「迴歸」更好。

例如,您可以要求某個組件通知您某個事件。在普通的Java中,你可能不得不阻止你的線程在某個鎖上。或者你可以推遲發送網絡請求,直到真正需要響應:產生需求的時刻是回調已準備好接受響應的時刻。

+0

我認爲這個解決方案會讓我延遲網絡通話。我想要的機制是,如果變量已經被初始化,則返回值沒有延遲,否則等待該值被初始化。 – Kain

+0

好吧,只需添加'.cacheWithInitialCapacity(1)'。我已經更新了答案(http://reactivex.io/RxJava/javadoc/rx/Observable.html#cacheWithInitialCapacity(int)) –

+0

您可能還需要添加'.take(1)',以確保您的訂戶獲取'onCompleted' –