Настройте ObservableTransformer с помощью RxJav/RxKotlin2 при использовании с compose()

Я пытаюсь написать функцию преобразования, которая используется с compose(), чтобы сократить шаблонный код. Это довольно просто:

    fun <R> withSchedulers(): ObservableTransformer<R, R> {
        return ObservableTransformer {
            it.subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
        }
    }

Так что каждый раз, когда я хочу подписаться на что-нибудь на ioThread и прослушать результат на mainThread, это всего лишь несколько строк кода:

    Observable.just(1)
        .compose(MyUtilClass.withSchedulers())
        .subscribe()

Но есть не только Observable, но и Single, Completable, Maybe и Flowable. Поэтому каждый раз, когда я хочу объединить их с моей функцией withSchedulers(), мне приходится преобразовывать ее в новый тип (чего я не ожидаю).

Например,

Completable.fromAction { 
        Log.d("nhp", "hello world")
    }//.compose(MyUtilClass.withSchedulers()) <-- This is not compiled
            .toObservable() <--- I have to transform it into Observable
            .compose(MyUtilClass.withSchedulers())
            .subscribe()

Итак, мой вопрос: есть ли способ написать вышеуказанную функцию для использования с compose() для любого типа Observable (Single, Completable,...)? Или нам нужно написать разные функции, которые используют ObservableTransformer, SingleTransformer, ....?


person nhp    schedule 03.01.2019    source источник


Ответы (1)


Я создал вспомогательный метод, используя тип reified:

inline fun <reified T> withSchedulers(): T {
    when (T::class) {
        ObservableTransformer::class  -> return ObservableTransformer<Unit, Unit> {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
        SingleTransformer::class      -> return SingleTransformer<Unit, Unit> {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
        CompletableTransformer::class -> return CompletableTransformer {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
    }
    throw IllegalArgumentException("not a valid Transformer type")
}

Примеры :

    Observable.just("1", "2")
            .compose(withSchedulers<ObservableTransformer<String, String>>())
            .subscribe(System.out::println)

    Single.just(3)
            .compose(withSchedulers<SingleTransformer<Int, Int>>())
            .subscribe(Consumer { println(it) })

    Completable.defer { Completable.complete()  }
            .compose(withSchedulers<CompletableTransformer>())
            .subscribe { println("completed") }

Выход :

1
2
3
completed

Возможно, есть и другие способы сделать это, но этот пришел на ум.

person Mark Keen    schedule 03.01.2019
comment
Я тоже думаю об этом. RxJava2 обеспечивает не дизайн наследования, а композицию. Поэтому я думаю, что это единственный способ добиться этого. Спасибо. Отметьте это как принятый ответ. - person nhp; 04.01.2019
comment
почему бы не использовать для этого функции расширения Kotlin? - person M. Wojcik; 06.05.2021
comment
В этом нет ничего плохого, но исходный вопрос специально включал compose() и Transformer, функции расширения не будут использовать Transformer, это будет только синтаксический сахар вокруг наблюдаемого/текущего. - person Mark Keen; 06.05.2021