Rx:WTFs

WARNING!

This presentation may contain drastic code snippets and is thus not suitable for underage and junior developers. Senior developer guidance is advised. Author of the presentation does not take responsibility for any damage caused by watching this presentation in person or online.

Reactive Extensions:

What The Threads

F

zip

zip

Let's play a game

@Test
fun `should be empty`() {
    obs.test().assertEmpty()
}

a) Observable.fromArray<Long>()
b) Observable.just(666L)
c) Observable.never<Long>()
d) Observable.interval(666L, SECONDS)
e) Observable.empty<Long>()
@Test
fun `should be empty`() {
    obs.test().assertEmpty()
}

a) Observable.fromArray<Long>()
b) Observable.just(666L)
c) Observable.never<Long>()
d) Observable.interval(666L, SECONDS)
e) Observable.empty<Long>()
Observable.zip(
    obsA.subscribeOn(computation()),
    obsB.subscribeOn(io()),
    BiFunction { a: Int, b: Int -> a + b })
Observable.zip(
    obsA.subscribeOn(computation()),
    obsB.subscribeOn(io()),
    BiFunction { a: Int, b: Int -> a + b })
Observable.zip(
    obsA.subscribeOn(computation()),
    obsB.subscribeOn(io()),
    BiFunction { a: Int, b: Int -> a + b })
    .subscribe()
Observable.zip(
    obsA.subscribeOn(io()),
    obsB.subscribeOn(computation()),
    BiFunction { a: Int, b: Int -> a + b })
    .subscribe()
Observable.zip(
    obsA.subscribeOn(io()),
    obsB,
    BiFunction { a: Int, b: Int -> a + b })
    .subscribe()

A: the horribly slow

val obs = Observable.zip(
    obsA.subscribeOn(io()),
    obsB.subscribeOn(io()),
    BiFunction { a: Int, b: Int -> a + b })
    .map { it * 666 }
    .doOnNext(::print)
obs.subscribe()
val obs = Observable.zip(
    obsA.subscribeOn(io()),
    obsB.subscribeOn(io()),
    BiFunction { a: Int, b: Int -> a + b })
    .map { it * 666 }
    .doOnNext(::print)
obs.subscribe()
obs.subscribe()

Beware of shared state inside these operators

observable
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }

    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
just(666).delay(666, MILLISECONDS, io())
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }

    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
interval(666, MILLISECONDS, io()).take(666)
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }

    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
observable
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }

    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
observable
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }

    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .doFinally { /* io */ }
    .observeOn(mainThread())
    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* main */ }
    .doFinally { /* io */ }
    .observeOn(mainThread())
    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .observeOn(mainThread())
    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .observeOn(mainThread())
    .doOnSubscribe { /* main */ }
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()

But my mama said there is no use of multiple subscribeOn

observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
disposable = observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
disposable.dispose()
disposable = observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .unsubscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
disposable.dispose()
disposable = observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .unsubscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .unsubscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
disposable.dispose()
disposable = observable
    .doOnSubscribe { /* io */ }
    .subscribeOn(io())
    .unsubscribeOn(io())
    .doFinally { /* io */ }
    .doOnSubscribe { /* main */ }
    .subscribeOn(mainThread())
    .unsubscribeOn(mainThread())
    .observeOn(mainThread())
    .doFinally { /* main */ }
    .subscribe()
disposable.dispose()

Thank you

Rx:WTFs / Google I/O extended 2017 Kraków

By Maciej Górski

Rx:WTFs / Google I/O extended 2017 Kraków

  • 1,702