RxKotlinの概要

1. 概要

このチュートリアルでは、RxKotlinライブラリを使用して、慣用的なKotlinでの* Reactive Extensions(Rx)の使用を確認します。*
RxKotlinは、Reactive Extensions自体の実装ではありません。 代わりに、それは主に拡張メソッドのコレクションです。 つまり、RxKotlinは、Kotlinを念頭に置いて設計されたAPIで* RxJava *ライブラリを強化します。
したがって、記事link:/rx-java[RxJavaの紹介]の概念と、_https://www.baeldung.com/rxjava-2-の概念を使用します。 flowable [Flowables] _専用の記事で紹介しました。

2. RxKotlinセットアップ

MavenプロジェクトでRxKotlinを使用するには、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22io.reactivex.rxjava2%22%20AND%20a%3Aを追加する必要があります。 _pom.xmlへの%22rxkotlin%22 [_rxkotlin_依存関係]:_
<dependency>
    <groupId>io.reactivex.rxjava2</groupId>
    <artifactId>rxkotlin</artifactId>
    <version>2.3.0</version>
</dependency>
または、Gradleプロジェクトの場合、_build.gradle:_
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
*ここでは、RxJava 2をターゲットとするRxKotlin 2.xを使用しています。* RxJava 1を使用するプロジェクトでは、RxKotlin 1.xを使用する必要があります。 同じ概念が両方のバージョンに適用されます。
RxKotlinはRxJavaに依存していますが、依存関係を最新リリースに頻繁に更新しないことに注意してください。 そのため、https://www.baeldung.com/rx-java#setup [RxJavaの記事]で詳しく説明されているように、依存する特定のRxJavaバージョンを明示的に含めることをお勧めします。

*3. RxKotlin *でObservablesを作成する

RxKotlinには、コレクションから_Observable_および_Flowable_オブジェクトを作成するための多くの拡張メソッドが含まれています。
特に、すべてのタイプの配列には_toObservable()_メソッドと_toFlowable()_メソッドがあります:*
val observable = listOf(1, 1, 2, 3).toObservable()
observable.test().assertValues(1, 1, 2, 3)
val flowable = listOf(1, 1, 2, 3).toFlowable()
flowable.buffer(2).test().assertValues(listOf(1, 1), listOf(2, 3))

* 3.1。 Completables *

RxKotlinは、https://www.baeldung.com/rxjava-completable [_Completable_]インスタンスを作成するいくつかのメソッドも提供します。 特に、拡張メソッド_toCompletable:_ *を使用して、__ Action__s、__ Callable__s、__ Future__s、およびゼロアリティ関数を_Completable_に変換できます。
var value = 0
val completable = { value = 3 }.toCompletable()
assertFalse(completable.test().isCancelled())
assertEquals(3, value)

*4. Observable_および_Flowable to Map_および_Multimap *

_Pair_インスタンスを生成する_Observable_または_Flowable_がある場合、それらを_Map:_を生成する_Single_オブザーバブルに変換できます。
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
val observable = list.toObservable()
val map = observable.toMap()
assertEquals(mapOf(Pair("a", 4), Pair("b", 2), Pair("c", 3)), map.blockingGet())
前の例で見ることができるように、_toMap_は、同じキーを持っている場合、前に出力された値を後の値で上書きします。
キーに関連付けられたすべての値をコレクションに蓄積する場合は、代わりに_toMultimap_を使用します。
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
val observable = list.toObservable()
val map = observable.toMultimap()
assertEquals(
  mapOf(Pair("a", listOf(1, 4)), Pair("b", listOf(2)), Pair("c", listOf(3))),
  map.blockingGet())

*5. ObservablesとFlowables *の組み合わせ

Rxのセールスポイントの1つは、__ Observable__sと__Flowable__sをさまざまな方法で組み合わせることができることです。 実際、RxJavaはすぐに使用できる多くの演算子を提供します。
それに加えて、RxKotlinには__Observable__sなどを組み合わせるための拡張メソッドがいくつか含まれています。

* 5.1。 観測可能な排出量の組み合わせ*

他の__Observable__sを発行する_Observable_がある場合、RxKotlinの拡張メソッドの1つを使用して、発行された値を結合できます。
特に、* _ mergeAll_はオブザーバブルと_flatMap:_ *を組み合わせます
val subject = PublishSubject.create<Observable<String>>()
val observable = subject.mergeAll()
これは次と同じです:
val observable = subject.flatMap { it }
結果の_Observable_は、ソース__Observable__sのすべての値を不特定の順序で出力します。
*同様に、_concatAll_は_concatMap_ *を使用します(値はソースと同じ順序で発行されます)。
これまで見てきたように、上記のすべてのメソッドは、_Flowable_ソースにも同じセマンティクスで提供されます。

* 5.2。 Completables Maybes、およびSingles *の組み合わせ

_Completable _、_ Maybe_、または_Single_のインスタンスを発行する_Observable_がある場合、たとえば_mergeAllMaybes_のような適切な_mergeAllXs_メソッドとそれらを組み合わせることができます。
val subject = PublishSubject.create<Maybe<Int>>()
val observable = subject.mergeAllMaybes()
subject.onNext(Maybe.just(1))
subject.onNext(Maybe.just(2))
subject.onNext(Maybe.empty())
subject.onNext(Maybe.error(Exception("error")))
subject.onNext(Maybe.just(3))
observable.test().assertValues(1, 2).assertError(Exception::class.java)

* 5.3。 Observables *のIterablesの組み合わせ

代わりに_Observable_または_Flowable_インスタンスのコレクションの場合、RxKotlinには_merge_および_mergeDelayError_という他の演算子がいくつかあります。 これらは両方とも、すべての__Observable__sまたは__Flowable__sを組み合わせて、すべての値を順番に出力するものになります:*
val observables = mutableListOf(Observable.just("first", "second"))
val observable = observables.merge()
observables.add(Observable.just("third", "fourth"))
observable.test().assertValues("first", "second", "third", "fourth")
RxJavaで同じ名前の演算子から直接派生した2つの演算子の違いは、*エラーの処理*です。
  • _merge_メソッドは、ソースから出力されるとすぐにエラーを出力します:*

// ...
observables.add(Observable.error(Exception("e")))
observables.add(Observable.just("fifth"))
// ...
observable.test().assertValues("first", "second", "third", "fourth")
一方、* _ mergeDelayError_はストリームの最後にそれらを出力します:*
// ...
observables.add(Observable.error(Exception("e")))
observables.add(Observable.just("fifth"))
// ...
observable.test().assertValues("first", "second", "third", "fourth", "fifth")

*6. 異なるタイプの値の処理+

*
次に、異なるタイプの値を処理するためのRxKotlinの拡張メソッドを見てみましょう。
これらはRxJavaメソッドのバリアントであり、Kotlinの具象ジェネリックを利用します。 特に、次のことができます。
  • 放出された値をあるタイプから別のタイプにキャストする、または

  • 特定のタイプではない値を除外

    したがって、たとえば、__ Number__sの_Observable_を___Int__sのいずれかにキャストできます。
val observable = Observable.just<Number>(1, 1, 2, 3)
observable.cast<Int>().test().assertValues(1, 1, 2, 3)
ここでは、キャストは不要です。 ただし、異なるオブザーバブルを組み合わせる場合、必要になる場合があります。
代わりに_ofType、_を使用すると、予期したタイプではない値をフィルターで除外できます。
val observable = Observable.just(1, "and", 2, "and")
observable.ofType<Int>().test().assertValues(1, 2)
いつものように、_cast_と_ofType_は__Observable__sと__Flowable__sの両方に適用できます。
さらに、__ Maybe __はこれらのメソッドもサポートしています。 代わりに、_Single_クラスは_cast_のみをサポートします。

7. その他のヘルパーメソッド

最後に、RxKotlinにはいくつかのヘルパーメソッドが含まれています。 簡単に見てみましょう。
_subscribe_の代わりに_subscribeBy_を使用できます。名前付きパラメーターを使用できます。
Observable.just(1).subscribeBy(onNext = { println(it) })
同様に、サブスクリプションをブロックするには、_blockingSubscribeBy._を使用できます。
さらに、RxKotlinにはRxJavaのメソッドを模倣するいくつかのメソッドが含まれていますが、Kotlinの型推論の制限を回避します。
たとえば、__Observable#zipを使用する場合、______zipperを指定すると__doesはあまり美しくありません。
Observable.zip(Observable.just(1), Observable.just(2), BiFunction<Int, Int, Int> { a, b -> a + b })
したがって、* RxKotlinは_Observables#zip_を追加して、より慣用的な使用法を提供します:*
Observables.zip(Observable.just(1), Observable.just(2)) { a, b -> a + b }
_Observables._の最後の「s」に注目してください。同様に、_Flowables、Singles、_および_Maybes._があります。

8. 結論

この記事では、RxJavaを強化してAPIを慣用的なKotlinのように見えるようにするRxKotlinライブラリを徹底的にレビューしました。
詳細については、https://github.com/ReactiveX/RxKotlin [RxKotlin GitHub page]を参照してください。 その他の例については、https://github.com/ReactiveX/RxKotlin/tree/2.x/src/test [RxKotlin tests]をお勧めします。
これらのすべての例とコードスニペットの実装は、MavenおよびGradleプロジェクトとしてhttps://github.com/eugenp/tutorials/tree/master/kotlin-libraries-2[GitHubプロジェクト]で見つけることができます。そのままインポートして実行できます。