web-dev-qa-db-ja.com

RxJavaのdoOnNext(...)の目的は何ですか

いつonNext()の代わりにObservableから doOnNext() を使用すべきですか?

51

doOnNextは副作用です:ロギングのような横方向の振る舞いのために、例えばストリームがフィルターされる前に、ストリームの中間ステップでアイテムの放出に反応(例えば、ログ)したいが、それでもストリームを伝播する値。

onNextはより最終的なもので、値を消費します。

75
Simon Baslé

重要な編集:-すぐ下に太字で

*概念を理解したら、これをご覧になることをお勧めします link 、これはライフチェンジャーであり、ObservableSingleMaybeは、Singleの場合はdoOnEvent()Observableの場合はdoOnEach()のように別のツールが必要になる場合がありますが、デバッグしたい場合、問題を解決するために関連する他のイベントを無視できるため、doOnNext()が理想的な選択にならない場合がいくつかあります*

元の返信:-部分的に変更-

まず、doOnNext()はObservableとSubscribeの間の演算子のチェーンでさらにさらに呼び出すことができます。これにより、コードをデバッグします。その「ストリーム」性のため、RXJavaでデバッグを行うのは簡単ではありません。代わりにdoOnNext()を使用するとデバッグが容易になります。この目的で、doOnError()演算子と組み合わせることも検討できます。単純なonNext()を使用しないのはなぜですか?デバッグはコードのロジックに厳密に関連していないため、理論的には、実稼働に入る前にdoOnNext()を削除することもできます。

理解すべき本当に重要なことは、Observableが長いチェーンをサブスクライブすると、特定のポイントでdoOnNextを使用して、オペレーターが別のオペレーターに何を返しているかを確認できることです。

例えば ​​:

Observable.just("Donald", "Duck", "Mickey", "Goofy",
                "Uncle")
                .doOnNext{System.out.println("Here ou will get the strings above:$it ")}
                 .map{it.length}
                 .subscribe { println("Here you will get the numbers of how every string is long: $it") }}

doOnNext()を使用する一般的な使用例は、たとえばサーバーからの応答をキャッシュする場合に発生する可能性があるため、たとえばmap()を使用できますが、 alsodoOnNext()。コードを読みやすくすることができます。代わりに、理想的には他の指示に従うように構造化された単純なonNext()を配置します。 (これはすべての建築思想と同様に議論の余地があります)

doOnNext()と同じで、同じデバッグ目的で、他の説明のつかない演算子を使用できます。

doOnSubscribe()、doOnUnsubscribe()、doOnCompleted()、doOnError()、doOnTerminate()、finallyDo()、doOnEach()、doOnRequest()

doOnNext()を使用すると、観測可能な(多くの場合非常に長い)チェーンに何が起こっているかを確認できます。本当に重要なことは、 、操作に影響を与えず、変換を行わずに(リアクティブコードではなく、命令型で使用するLog.dの種類が適切でないとしましょう)side効果。

編集(コメント内の質問のため):

doOnNext()と上記のメソッドは単なるコールバックです。公式ドキュメントにあるように thatdoOnNext()を参照してください

onNextを呼び出すときにアクションを呼び出すようにObservableを変更します。

本当にシンプルなため、これはプログレスバーをアップロードするために呼び出されることがありますが、たとえば、retrofitの呼び出し後にデータをdb /またはキャッシュに保存する場合など、リポジトリパターンでも実際に使用されます。

内部で本当に興味がある場合、doSomethingReactiveメソッドは、「実際の」メソッドSomethingReactive内でメソッドcall()(インターフェイスアクションからのコールバック)を呼び出すだけです。

18
trocchietto