Inleiding tot RxKotlin

1. Overzicht

In deze tutorial gaan we het gebruik van Reactive Extensions (Rx) in idiomatische Kotlin met behulp van de RxKotlin-bibliotheek.

RxKotlin is niet per se een implementatie van Reactive Extensions. In plaats daarvan is het meestal een verzameling uitbreidingsmethoden. Dat wil zeggen, RxKotlin vergroot de RxJava bibliotheek met een API ontworpen met Kotlin in gedachten.

Daarom gebruiken we concepten uit ons artikel, Inleiding tot RxJava, evenals het concept van Flowables we hebben gepresenteerd in een speciaal artikel.

2. RxKotlin instellen

Om RxKotlin in ons Maven-project te gebruiken, moeten we de rxkotlin afhankelijkheid van onze pom.xml:

 io.reactivex.rxjava2 rxkotlin 2.3.0 

Of, voor een Gradle-project, naar ons build.gradle:

implementatie 'io.reactivex.rxjava2: rxkotlin: 2.3.0'

Hier gebruiken we RxKotlin 2.x, dat zich richt op RxJava 2. Projecten die RxJava 1 gebruiken, moeten RxKotlin 1.x gebruiken. Dezelfde concepten zijn van toepassing op beide versies.

Merk op dat RxKotlin afhankelijk is van RxJava, maar dat ze de afhankelijkheid niet regelmatig bijwerken naar de laatste release. We raden dus aan om expliciet de specifieke RxJava-versie op te nemen waarvan we afhankelijk zullen zijn, zoals beschreven in ons RxJava-artikel.

3. Creëren Waarneembaars in RxKotlin

RxKotlin bevat een aantal uitbreidingsmethoden om Waarneembaar en Vloeiend objecten uit verzamelingen.

Vooral, elk type array heeft een toObservable () methode en een toFlowable () methode:

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. Voltooibaars

RxKotlin biedt ook enkele methoden om Voltooibaar gevallen. Vooral, we kunnen converteren Acties, Oproepbaars, Toekomsts en zero-arity-functies naar Voltooibaar met de uitbreidingsmethode te voltooien:

var waarde = 0 val completable = {waarde = 3} .toCompletable () assertFalse (completable.test (). isCancelled ()) assertEquals (3, waarde)

4. Waarneembaar en Vloeiend naar Kaart en Multimap

Als we een Waarneembaar of Vloeiend dat produceert Paar gevallen, kunnen we ze omzetten in een Single waarneembaar dat een Kaart:

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 ())

Zoals we in het vorige voorbeeld kunnen zien, in kaart brengen overschrijft waarden die eerder zijn verzonden met latere waarden als ze dezelfde sleutel hebben.

Als we alle waarden die aan een sleutel zijn gekoppeld in een verzameling willen verzamelen, gebruiken we naarMultimap in plaats daarvan:

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. Combineren Waarneembaars en Vloeiends

Een van de verkoopargumenten van Rx is de mogelijkheid om te combineren Waarneembaars en Vloeiends op verschillende manieren. Inderdaad, RxJava biedt een aantal operators uit de doos.

Daarnaast bevat RxKotlin nog een paar uitbreidingsmethoden om te combineren Waarneembaars en dergelijke.

5.1. Waarneembare emissies combineren

Als we een Waarneembaar dat straalt andere uit Waarneembaars, kunnen we een van de uitbreidingsmethoden in RxKotlin gebruiken om de uitgezonden waarden te combineren.

Vooral, mergeAll combineert de observabelen met platte kaart:

val subject = PublishSubject.create() val observable = subject.mergeAll ()

Wat hetzelfde zou zijn als:

val observable = subject.flatMap {it}

Het resultaat Waarneembaar zal alle waarden van de bron uitzenden Waarneembaars in een niet-gespecificeerde volgorde.

Evenzo concatAll toepassingen concatMap (de waarden worden in dezelfde volgorde verzonden als de bronnen), terwijl switchLatest toepassingen switchMap (waarden worden uitgezonden vanaf de laatst uitgezonden Waarneembaar).

Zoals we tot nu toe hebben gezien, alle bovenstaande methoden zijn voorzien Vloeiend bronnen ook, met dezelfde semantiek.

5.2. Combineren Voltooibaars,Kan zijns, en Singles

Als we een Waarneembaar dat voorbeelden uitzendt van Voltooibaar, Kan zijn, of Singlekunnen we die combineren met de juiste mergeAllXs methode zoals bijvoorbeeld mergeAllMaybes:

val subject = PublishSubject.create() val observable = subject.mergeAllMaybes () subject.onNext (Misschien.just (1)) subject.onNext (Misschien.just (2)) subject.onNext (Misschien.empty ()) subject.onNext (Misschien.error ( Uitzondering ("fout"))) subject.onNext (Misschien.just (3)) observable.test (). AssertValues ​​(1, 2) .assertError (Uitzondering :: class.java)

5.3. Combineren Herhaalbaars van Waarneembaars

Voor collecties van Waarneembaar of Vloeiend instanties in plaats daarvan heeft RxKotlin een paar andere operators, samenvoegen en mergeDelayError. Ze hebben allebei het effect van het combineren van alle Waarneembaars of Vloeiends in een die alle waarden achter elkaar uitzendt:

val observables = mutableListOf (Observable.just ("eerste", "tweede")) val observable = observables.merge () observables.add (Observable.just ("derde", "vierde")) observable.test (). assertValues ("eerste tweede derde vierde")

Het verschil tussen de twee operatoren - die rechtstreeks zijn afgeleid van dezelfde operatoren in RxJava - is hun behandeling van fouten.

De samenvoegen methode geeft fouten zodra ze door de bron worden verzonden:

// ... observables.add (Observable.error (uitzondering ("e"))) observables.add (Observable.just ("vijfde")) // ... observable.test (). assertValues ​​("eerste" , "tweede", "derde", "vierde")

Terwijl mergeDelayError zendt ze uit aan het einde van de stream:

// ... observables.add (Observable.error (uitzondering ("e"))) observables.add (Observable.just ("vijfde")) // ... observable.test (). assertValues ​​("eerste" , "tweede", "derde", "vierde", "vijfde")

6. Omgaan met waarden van verschillende typen

Laten we nu kijken naar de uitbreidingsmethoden in RxKotlin voor het omgaan met waarden van verschillende typen.

Dit zijn varianten van RxJava-methoden, die gebruik maken van Kotlin's reified generics. In het bijzonder kunnen we:

  • cast uitgezonden waarden van het ene type naar het andere, of
  • filter waarden uit die niet van een bepaald type zijn

We kunnen dus bijvoorbeeld een Waarneembaar van Aantals naar een van Ints:

val observable = Observable.just (1, 1, 2, 3) observable.cast (). test (). assertValues ​​(1, 1, 2, 3)

Hier is de cast niet nodig. Wanneer we echter verschillende observabelen samen combineren, hebben we het misschien nodig.

Met ofType, in plaats daarvan kunnen we waarden filteren die niet van het type zijn dat we verwachten:

val observable = Observable.just (1, "en", 2, "en") observable.ofType (). test (). assertValues ​​(1, 2)

Zoals gewoonlijk, gips en ofType zijn van toepassing op beide Waarneembaars en Vloeiends.

Verder Kan zijn ondersteunt deze methoden ook. De Single class ondersteunt in plaats daarvan alleen gips.

7. Andere hulpmethoden

Ten slotte bevat RxKotlin verschillende hulpmethoden. Laten we snel kijken.

We kunnen gebruiken abonneren in plaats van abonneren - het staat benoemde parameters toe:

Observable.just (1) .subscribeBy (onNext = {println (it)})

Evenzo kunnen we voor het blokkeren van abonnementen blokkerenSubscribeBy.

Bovendien bevat RxKotlin enkele methoden die die in RxJava nabootsen, maar een beperking van de type-inferentie van Kotlin omzeilen.

Bijvoorbeeld bij het gebruik van Waarneembare # zip, specificeren van de rits ziet er niet zo goed uit:

Observable.zip (Observable.just (1), Observable.just (2), BiFunction {a, b -> a + b})

Zo, RxKotlin voegt toe Waarneembare # zip voor meer idiomatisch gebruik:

Observables.zip (Observable.just (1), Observable.just (2)) {a, b -> a + b}

Let op de laatste "s" in Waarneembare. Evenzo hebben we Flowables, Singles, en Maybes.

8. Conclusies

In dit artikel hebben we de RxKotlin-bibliotheek grondig bekeken, die RxJava uitbreidt om de API meer op het idiomatische Kotlin te laten lijken.

Raadpleeg de RxKotlin GitHub-pagina voor meer informatie. Voor meer voorbeelden raden we RxKotlin-tests aan.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in het GitHub-project als een Maven- en Gradle-project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.