2016-12-09 5 views
0

ので、最初に、私は私が持っていると私は考えることはそこに何が起こるかを紹介します:実行doOnNexは

private BehaviorSubject<DataObject> dataSubject = BehaviorSubject.create(); 

私は特定に戻ってそれを与える:

私はBehavourSubject<DataObject>持っていますこのようになります機能:私はそれが起こると仮定何

public Observable<DataObject> pendingData() { 
    return this.dataSubject.asObservable() 
     .doOnNext(data -> { 
      // do something with this data that has to be thread save. 
     }) 
     .observeOn(AndroidSchedulers.mainThread()); 
} 

がdoOnNext部分はそのthis.dataSubject.onNext(data);で、同じスレッドで実行されること、であるが呼び出されます。しかし、私はこのラムダでスレッドを節約する必要がある何かを行うと、私はセマフォーに入れたり、特定のスレッドですべてのdoOnNextアクションを実行する必要があります。

私の最初のアイデアは「rxのスレッドを処理する通常の方法」ですが、うまくいきません。 私はこのような観測可能にsubscribeOn(certainBackgroundScheduler)を追加するために考えた:

public Observable<DataObject> pendingData() { 
    return this.dataSubject.asObservable() 
     .doOnNext(data -> { 
      // do something with this data that has to be thread save. 
     }) 
     .subscribeOn(certainBackgroundScheduler) 
     .observeOn(AndroidSchedulers.mainThread()); 
} 

しかし、私は、サブスクリプション・ブロックで観察を作成するときは、このブロックはその backgroundSchedulerで実行されています。私がサブスクライバで onNextを呼び出すと、そのスレッドでは論理的ですが、それはBehaviorSubjectで同じですか?

本当に簡単ですか?もしそうでなければ、被験者に特定のスレッドのdoOnNextブロックを強制的に実行させることができますか?

+0

試してみるとうまくいかないのですか? – weston

答えて

1

本当に簡単ですか?そうでなければ、どうすればサブジェクトが特定のスレッドのdoOnNextブロックを実行させることができますか?

はい、そうです。さらに明確にするために、docssubscribeOnobserveOnを読んでください。

+0

'doOnNext'ブロックは' subscribeOn'メソッドではなく 'observeOn'メソッドによって渡されるスレッドで実行されますか? –

+0

私は少し間違っていました。だからあなたの最後のコードスニペットで '.doOnNext'が' certainBackgroundScheduler'で実行されます。これは 'Thread.currentThread()'メソッドで簡単に確認できます。したがって、docが言うように、あなたの仕事はあなたが購読しているスケジューラーでデフォルトで観察されます。 –

+0

答えが正しいように編集できますか? –

2

チェーン内に複数のobserveOnを置くことができます。異なる実行「場所」間で値をルーティングできます。

dataSubject 
.observeOn(backgroundScheduler) 
.doOnNext(v -> /* this will run on another scheduler. */) 
.observeOn(AndroidSchedulers.mainThread()) 
.doOnNext(v -> /* this will run on main after the previous */) 
関連する問題