Как стать автором
Обновить

Комментарии 16

Извините, но код корутин ужасен :/

Да и Rx-код тоже не подарок...

Вообще, все сравнение очень странное - каждый раз, когда RxJava предлагают, как фреймворк для асинхронного программирования, хочется выть. Это как гвозди микроскопом забивать.

Так у автора и Rx код малость неумело написан :) Этот фреймворк редко кто знает в должной мере, чтобы не плодить ужасы. Самый большой минус Rx - это очень высокий порог входа. Именно поэтому он перестает быть популярен, что входящих в разработку стало ну много

У автора он не очень аккуратно написан. Можно лучше:

private suspend fun loadImages() {
    withContext(Dispatchers.IO) {
        loadEmails()
    }
    withContext(Dispatchers.Main) {
        emailView.setAdapter(
            ArrayAdapter(
                applicationContext,
                android.R.layout.simple_dropdown_item_1line,
                getEmails()
            )
        )
    }
}

К тому же эту функцию стоит сделать `suspend`, т.к. в реализации автора возможна утечка памяти

Можно еще немного "улучшить".
С большой долей вероятности, скоуп, в котором будет вызыватся эта функция уже будет построен на Main диспатчере (скоуп активити/фрагмента/вьюмодели). Соответсвенно, второе переключение контекста можно опустить.

Я бы не стал закладываться на такое предположение. Но можно сделать лучше, вместо `Dispatchers.Main` написать `Dispatchers.Main.immediate`. Так, если, поток уже Main, то переключения не произойдет

Насколько я знаю, предложенное greennick выше является хорошим тоном, во фрагментах и активити вызывать корутины именно на мэйн

В таком случае, возможно, стоит пометить метод аннотацией `@MainThread`. Но, мне кажется, что лучше дополнительно перестраховаться. Это не дорого, в случае использования `Dispatchers.Main.immediate` переключения потока не призойдет

Здесь дело не в коде, а в подходе, смысл статьи был показать что на корутинах код понятнее и читабельнее, код для статьи я писал на коленочке,

Минус Rx в том, что в нем довольно сложно разобраться так, чтобы писать аккуратный и понятный код. В вашем примере вы используете подход создания Observable, характерный для древней первой версии библиотеки. Сейчас это делается гораздо проще; более того, источники обычно создавать не нужно - Retrofit & Co давно умеют отдавать контракт Rx на выходе. К тому же, я так и не понял зачем в подписке создавать ArrayAdapter. Вы и про жизненный цикл не упомянули, и ваш пример будет утекать :\

Вот так мог бы выглядеть ваш код (жизненный цикл не завозил за неимением деталей использования примера):

abstract class Example {

        fun pullEmails() {
            Single.fromCallable { loadEmails() }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::setViewItems)
        }

        abstract fun loadEmails(): List<String>

        abstract fun setViewItems(items: List<String>)
    }

Если же loadEmails ведет, например, в ретрофит, то даже fromCallable() не нужен

Но в реальных проектах все чаще вижу как раз неумелое использование Rx, где в subscribe вкорячивают лямбду на 200 строк и творят другую дичь. Просто сборник "как делать в Rx не надо"

Спасибо за комментарий, просто код для данной статьи я писал на коленке и над чистотой кода я не замолачивался, просто посыл данной стать был немного другой показать наглядно что при использовании корутин код становиться читабельнее и понятнее воспринимается на глаз

Ну, так можно любой фреймворк выставить в неприглядном свете, если не заморачиваться :)

Не увидел преимуществ. Везде, где речь идет о Java vs Kotlin, единственным преимуществом называют красивый и читабельный код. А здесь пример еще более странной борьбы за красоту кода в пределах Kotlin.
Если программирую на Java, то у меня обычно нет проблем прочитать код.
Главный вопрос, который должен подниматься при сравнении разных подходов — что будет работать быстрее, и на сколько быстрее. Читабельность кода сегодня, мне кажется, не так критична. Должен быть баланс между читабельностью, скоростью разработки и скоростью работы итогового приложения.

А кто-нибудь понимает как сделать аналог Observable.amb (запуск нескольких операций паралельно, возврат результата только, как только сработает первая операция, остальные отменяются)?

Можно так https://arrow-kt.io/docs/fx/parallel/index.html#racing-parallel-operations, см раздел raceN. В kotlinx.coroutines пока нет из коробки, но есть issue https://github.com/Kotlin/kotlinx.coroutines/issues/2867. Напишите туда, зачем такая функция нужна. Может быстрее добавят)

С Handler'ом всё так. Про Rx не знал, но видимо и не нужно было. Корутины - интересно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории