LoginSignup
13
11

More than 5 years have passed since last update.

【RxJava】doOnSubscribe, doFinallyで処理をちょっぴりスマートに書く

Posted at

こんな書き方も出来るのか、と思ったのでメモがてら投稿
(バージョンはRxJava 2.1.9です。)

同じ処理が2箇所に…

MVPとかでアプリを実装していると、Presenterで下記のようなコードを書くことがあるかと思います。

SamplePresenter.kt

override fun onClick() {
    view.showProgress()

    sampleInteractor.getItems()
        .subscribeBy(
            onSuccess = {

                // do something

                view.hideProgress()
            },
            onError = {

                // error handling

                view.hideProgress()
            }
        ).addTo(disposable)
}

Viewからクリックのイベントが来たら、プログレスを表示し、何かしらの処理をし、成功した場合(onSuccess)or エラーが発生した場合(onError)それぞれでプログレスを非表示にする、という感じのよくある処理ですね。

ここで気になるのは view.hideProgress() という処理が2箇所にある、というところです。同じ処理があるならば、なんとか1箇所で書けないものか…

そんな時に使えるのが doFinally です。

doFinally

Javadocには

Calls the specified action after this Single signals onSuccess or onError or gets disposed by the downstream.

と記載されており、成功時・エラー時・破棄された時(disposed)に呼ばれるようです。つまるところ、何かしら最後に呼びたいものがあったらここに書けばいい、ということですね。(ここは少し自信が無いポイントです :sweat:

先程のコードに戻ると、 view.hideProgress() が最後に呼びたい処理ですので、 doFinally を使うと下記のように書くことが出来ます。

SamplePresenter.kt

override fun onClick() {
    view.showProgress()

    sampleInteractor.getItems()
        .doFinally {
            view.hideProgress()
        }
        .subscribeBy(
            onSuccess = {
                // do something
            },
            onError = {
                // error handling
            }
        ).addTo(disposable)
}

2箇所に散らばっていたview.hideProgress()を1箇所にまとめることが出来ました!
今回は共通して行っていた処理がview.hideProgress()だけでしたが、複数の処理を重複して onSuccess onError で行っていた場合は、だいぶ見通しが良くなるのではないかと思います。また、書き忘れ防止にも役立つのでは、と感じました。

さて、この段階でコードとしてはもう十分かな、と思ってしまうのですが、view.showProgress()だけ孤立した感じになっているので、どうせならRxの流れに沿って記述したい…!

そんな時に使えるのが doOnSubscribe です。

doOnSubscribe

Javadocには

Calls the shared consumer with the Disposable sent through the onSubscribe for each SingleObserver that subscribes to the current Single.

と記載されており、subscribe した時に呼ばれるみたいです。

早速 doOnSubscribe を使って書き直してみます。

SamplePresenter.kt

override fun onClick() {
    sampleInteractor.getItems()
        .doOnSubscribe {
            view.showProgress()
        }
        .doFinally {
            view.hideProgress()
        }
        .subscribeBy(
            onSuccess = {
                // do something
            },
            onError = {
                // error handling
            }
        ).addTo(disposable)
}

孤立した感じになっていたview.showProgress()が、うまいことRxの流れに沿うようになり、ちょっぴりスマートに書くことが出来のでは、と思います! :smile:

まとめ

  • 2箇所に散らばっていた処理を doFinally を使うことで1箇所にまとめることができました。
  • doOnSubscribeを使うことで、Rxの流れに沿って記述出来るようにもなりました。

RxJavaはまだまだ知らなかった機能・便利な機能があるはずなので、もっとスマートに書くべく勉強していきたい :muscle:

参考

【RxJavaを使った通信中にProgressダイアログを出す】
https://qiita.com/boohbah/items/e8010730725c54f85a3a

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11