Grokayem RxJava、パート3:利益と反応

最初の部分では、RxJavaの基本について説明しました。 第二部では、オペレーターの可能性を示しました。 しかし、おそらく私が示したすべてはあなたを納得させるにはまだ十分ではありません。 この場合、さらにいくつかのRxJavaユーティリティを紹介しますが、これは決定的な議論になるはずです。

エラー処理


これonError() onComplete()onError()などのObservableメソッドを完全に無視しました。 これらのメソッドは、 Observableが新しいデータの生成を停止したときに、それ以上生成するものがないか、エラーが発生したために呼び出されます。
最初のSubscriber onCompleted()およびonError()監視しonCompleted() 。 これらのポイントで何か役に立つことをしましょう:

 Observable.just("Hello, world!") .map(s -> potentialException(s)) .map(s -> anotherPotentialException(s)) .subscribe(new Subscriber<String>() { @Override public void onNext(String s) { System.out.println(s); } @Override public void onCompleted() { System.out.println("Completed!"); } @Override public void onError(Throwable e) { System.out.println("Ouch!"); } }); 



potentialException()およびanotherPotentialException()が実行時に例外をスローできるとします。 各Observableは、 onCompleted()またはonError呼び出して実行を完了します。 この場合、プログラムの出力は文字列の後に「Completed!」が続くか、出力が単一の「Ouch!」で構成されます(例外がスローされたため)。

したがって、いくつかの結論があります。

  1. onError()例外がいつスローされたかに関係なく発生します。
    これにより、エラー処理が非常に簡単になります。最後にある1つの関数で発生する各エラーを簡単に処理できます。
  2. オペレーターは例外を処理する必要はありません。
    Observablesチェーンのどこかで発生するエラーの処理は、次のようにSubscriberタスクになります。 各例外はonError()直接続きます。
  3. Subscriberが新しいアイテムの受信を停止したことはいつでもわかります。
    いつシャットダウンするかを知ることで、より一貫性のあるコードを書くことができます(ただし、 Observableが完了しないこともあります)。

エラー処理に対するこのアプローチは、従来のアプローチよりもはるかに簡単だと思います。 コールバック関数を使用してコードを記述している場合、それぞれでエラー処理が発生するはずです。 これは、コードが多くの場所で繰り返され始めるという事実につながるだけでなく、 コールバック関数がエラーの処理方法を認識しなければならないという事実につながります。
RxJavaの場合、 Observableはエラーの処理方法さえ知らないはずです! これは演算子にも適用されます。前の段階のいくつかで重大なエラーが発生した場合、それらは実行されません。 すべてのエラー処理はSubscriberます。

プランナー


ネットワークへのリクエストを行うAndroidアプリケーションがあります。 リクエストには時間がかかる場合があるため、別のスレッドに移動します。 あなたには、あなたがどのように問題を抱えているかを振り返る時間すらありません。
マルチスレッドAndroidアプリケーションは、正しいスレッドで正しいコードを実行することを確認する必要があるため、作成が困難です。 何かを混乱させると、アプリケーションがクラッシュします。 典型的な例は、メインスレッドからではなく、 Viewステートを変更しようとしたことに応じて発生する例外です。
RxJavaでは、それぞれsubscribeOn()observeOn()を使用して、 ObserverSubscriberを起動するスレッドを簡単に指定できます。

 myObservableServices.retrieveImage(url) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(bitmap -> myImageView.setImageBitmap(bitmap)); 

ちょうどいい? Subscriberが別のI / Oストリームで実行される前に行われるすべての処理、およびViewを使用した操作は、メインストリーム1で既に機能しています。
ここで興味深いのは、 subscribeOn()observeOn()は、単なるObservableで呼び出すことができるということです。 Observable()動作やそれに続く演算子を心配する必要はありません-必要なスレッドでタスクの実行を分散させるために、最後にsubscribeOn()observeOn()を追加するだけです。
AsyncTaskなどを使用する場合は、どの部分を並列に実行するかを考慮してコードを記述する必要があります。 RxJavaの場合、単純にコードを記述し、それを実行する場所を示します2

サブスクリプション


私はまだあなたから隠れている1つのポイントがあります。 Observable.subscribe()を呼び出すと、 ObservableSubscriber接続であるSubscriptionクラスのオブジェクトが返されます。

 Subscription subscription = Observable.just("Hello, World!") .subscribe(s -> System.out.println(s)); 

将来、 Subscriptionを終了するには、受け取ったSubscriptionを使用できます。

 subscription.unsubscribe(); System.out.println("Unsubscribed=" + subscription.isUnsubscribed()); //  "Unsubscribed=true" 

サブスクリプションをキャンセルすると、RxJavaは記述したチェーン全体を停止します。つまり、多くの演算子で構成される大きな変換チェーンを記述した場合、unsubscribeは現在実行中のコードに関係なく実行を停止します。 3これ以上は必要ありません。

おわりに


この一連の記事は、RxJavaの紹介にすぎないことに注意してください。 私の紹介があなたにとって花のように見えるのと比較して、興味深い複雑な資料がたくさんあります(信じられない- 背圧について読んでください)。 私はどこでもリアクティブなコードを書くつもりはありませんが、シンプルで理解可能な方法で書き直したいコードのより複雑なセクションのためにそれを保存します。
最初は3つの記事で十分だと思っていましたが、多くの人がAn​​droidでRxJavaを使用するいくつかの実用的な例を示すように頼み、別の記事を書きました 。 このすばらしいフレームワークを試してみるよう説得するのに、私の紹介が十分であったことを願っています。 調査をさらに深く掘り下げたい場合は、公式wikiページを読むことをお勧めします 。 そして、覚えておいてください: 不可能は存在しません

エラーと不正確さについてこの記事を読んでくれたすべての人々に感謝します: MatthiasKäpplerMatthew WearUlysses PoppleHamid PaloJoel Drotos (あごひげだけで見てください)。



1これは、 Subscriberを可能な限り軽量にする必要がある理由の1つです。つまり、メインスレッドを必要以上にブロックしないようにするためです。
2ときどき、 observeOn()およびsubscribeOn()の使用の真実がobserveOn()れる場合があります。 たとえば、 Observableが長期間機能すると約束した場合でも、 SubscriberはI / Oストリームで実行されますが、後者を新しいストリームに転送する理由はありません。
3 最初の部分で、 Observable.just()onNext()およびonCompleted()呼び出すObservableと同じではないことに気付きました。 そしてポイントはサブスクリプションにありますonNext()場合、 onNext()呼び出す前に、 Subscriberがまだ署名されているかどうかをチェックします。

Source: https://habr.com/ru/post/J265727/


All Articles