2016-11-27 6 views
4

私はネットワークコールで初期化されたクラス変数を持っています。RxJava:以前のサブスクリプションで値を初期化するのを待つ方法は?

初期化された場合、ゲッターのようなメソッドが返されます。ネットワークコールがまだ返されていない場合に値が初期化されるのを待っています。

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がコールバック・ベースです。だから、あなたが観測可能なものから何かを得たいときは、 'return observable.get()'と言うのではなく、観測可能な内容を受け取るコールバックを提供しています。多分。実際にコンテンツがあるとき、実際に。

コンセプトの周りを頭で囲むには、精神的な努力が必要です。 RxJavaでは、 'return'キーワードを入力することはめったにないので、代わりにコールバックを渡します。これは最初は変だと感じることがありますが、場合によってはコールバックが「戻る」よりも優れています。

たとえば、一部のイベントについて通知するようにコンポーネントに依頼することができます。単純なJavaでは、おそらくあなたのスレッドをいくつかのロックでブロックする必要があります。または、応答が本当に必要になるまで、送信ネットワーク要求を延期することができます。応答を受け入れる準備ができたコールバックがある瞬間が必要になる瞬間です。

+0

私はこの解決策が私にネットワークコールの遅れを与えてくれると思います。私が望んだ主張は、変数がすでに初期化されていれば値を返すための遅延がなく、値が初期化されるのを待つだけです。 – Kain

+0

'.cacheWithInitialCapacity(1)'を追加するだけです。私は答えを更新しました。(http://reactivex.io/RxJava/javadoc/rx/Observable.html#cacheWithInitialCapacity(int)) –

+0

また、 '.take(1)'を追加する必要があります。加入者は 'oncompleted'を取得します –

関連する問題