Подтвердить что ты не робот

Как Kotlin coroutines лучше, чем RxKotlin?

Зачем мне использовать сопрограммы Kotlin?

Кажется, библиотека RxKotlin гораздо более универсальна. Сопрограммы Kotlin выглядят значительно менее мощными и более громоздкими в сравнении.

Я основываю свое мнение на сопрограммах на этом выступлении Андрея Бреслава (JetBrains): https://www.youtube.com/watch?v=4W3ruTWUhpw

Слайд-шоу из выступления доступно здесь: https://www.slideshare.net/abreslav/jvmls-2016-coroutines-in-kotlin


РЕДАКТИРОВАТЬ (спасибо @hotkey):

Лучший источник информации о текущем состоянии сопрограмм: https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md

4b9b3361

Ответ 1

В Rx есть две части; Наблюдаемый паттерн и солидный набор операторов для манипулирования, преобразования и комбинирования их. Наблюдаемый паттерн сам по себе мало что делает. То же самое с сопрограммами; это просто еще одна парадигма, связанная с асинхронизмом. Вы можете сравнить плюсы и минусы обратных вызовов, Observable и сопрограмм для решения данной проблемы, но вы не можете сравнить парадигму с полнофункциональной библиотекой. Это как сравнивать язык с фреймворком.

Насколько сопрограммы Kotlin лучше, чем RxKotlin? Еще не использовал сопрограммы, но это похоже на async/wait в С#. Вы просто пишете последовательный код, все так же просто, как писать синхронный код... за исключением того, что он выполняется асинхронно. Это легче понять.

Зачем мне использовать сопрограммы kotlin? Я отвечу за себя. Большую часть времени я буду придерживаться Rx, потому что я предпочитаю управляемую событиями архитектуру. Но если возникнет ситуация, когда я пишу последовательный код и мне нужно вызывать асинхронный метод в середине, я с радостью использую сопрограммы, чтобы сохранить его таким образом и избегать оборачивания всего в Observable.

Редактировать: Теперь, когда я использую сопрограммы, пришло время для обновления.

RxKotlin - это просто синтаксический сахар для использования RxJava в Kotlin, поэтому я буду говорить о RxJava, а не о RxKotlin в следующем. Сопрограммы являются более низким рычагом и более общей концепцией, чем RxJava, они служат другим сценариям использования. Тем не менее, есть один вариант использования, где вы можете сравнить RxJava и сопрограммы (channel), он передает данные асинхронно. Сопрограммы имеют явное преимущество перед RxJava здесь:

С сопрограммами лучше иметь дело с ресурсами

  • В RxJava можно назначить вычисления для планировщиков, но subscribeOn() и ObserveOn() запутаны. Каждая сопрограмма получает контекст потока и возвращается в родительский контекст. Для канала обе стороны (производитель, потребитель) выполняют в своем собственном контексте. Сопрограммы более интуитивно понятны при воздействии на поток или пул потоков.
  • Сопрограммы дают больше контроля над тем, когда эти вычисления происходят. Например, вы можете передать hand (yield), расставить приоритеты (select), распараллелить (несколько producer/actor на channel) или заблокировать ресурс (Mutex) для данного вычисления. Это может не иметь значения на сервере (где RxJava пришел первым), но в среде с ограниченными ресурсами этот уровень контроля может потребоваться.
  • Из-за реактивного характера противодавление не очень хорошо в RxJava. С другой стороны, send() для канала - это функция приостановки, которая приостанавливается при достижении пропускной способности канала. Это нестандартное противодавление, данное природой. Вы также можете offer() для канала, и в этом случае вызов никогда не приостанавливается, а возвращает false если канал заполнен, эффективно воспроизводя onBackpressureDrop() из RxJava. Или вы можете просто написать свою собственную логику противодавления, что не составит труда с сопрограммами, особенно по сравнению с тем же с RxJava.

Есть еще один вариант использования, где сияют сопрограммы, и это ответит на ваш второй вопрос "Зачем мне использовать сопрограммы Kotlin?". Сопрограммы являются идеальной заменой фоновых потоков или AsyncTask (Android). Это так же просто, как launch { someBlockingFunction() }. Конечно, вы могли бы добиться этого и с RxJava, используя Schedulers и Completable возможно. Вы не будете (или мало) будете использовать шаблон Observer и операторы, которые являются сигнатурой RxJava, намек на то, что эта работа выходит за рамки RxJava. Сложность RxJava (бесполезный налог здесь) сделает ваш код более многословным и менее чистым, чем версия Coroutine.

Читаемость имеет значение. В этом отношении подходы RxJava и сопрограммы сильно различаются. Сопрограммы проще, чем RxJava. Если вам не очень flatmap() с map(), flatmap() и функционально-реактивным программированием в целом, манипуляции с сопрограммами проще, включая базовые инструкции: for, if, try/catch... Но лично я нахожу код сопрограммы труднее для понимания нетривиальные задачи. Особенно это связано с большим количеством вложений и отступов, в то время как цепочка операторов в RxJava поддерживает все в порядке. Функциональное программирование делает обработку более явной. Кроме того, RxJava может решать сложные преобразования с помощью нескольких стандартных операторов из их расширенного (ОК, слишком богатого) набора операторов. RxJava сияет, когда у вас сложные потоки данных, требующие большого количества комбинаций и преобразований.

Я надеюсь, что эти соображения помогут вам выбрать правильный инструмент с учетом ваших потребностей.

Ответ 2

Котлин сопрограммы отличаются от Rx. Трудно сравнить их яблоки с яблоками, потому что сопрограммы Kotlin - это тонкая языковая функция (всего лишь пара основных понятий и несколько основных функций для управления ими), в то время как Rx - довольно тяжелая библиотека с довольно большим разнообразием готовые операторы. Оба предназначены для решения проблемы асинхронного программирования, однако их подход к решению очень отличается:

  • Rx поставляется с особым функциональным стилем программирования, который может быть реализован практически на любом языке программирования без поддержки самого языка. Это хорошо работает, когда рассматриваемая проблема легко разлагается на последовательность стандартных операторов, и не очень хорошо в противном случае.

  • Сопрограммы Kotlin предоставляют языковую функцию, которая позволяет авторам библиотек реализовывать различные стили асинхронного программирования, включая, но не ограничиваясь, функционально-реактивный стиль (Rx). С сопрограммами Kotlin вы также можете написать свой асинхронный код в императивном стиле, в стиле обещания/будущего, в стиле актера и т.д.

Более уместно сравнивать Rx с некоторыми конкретными библиотеками, которые реализованы на основе сопрограмм Котлина.

Возьмите библиотеку kotlinx.coroutines в качестве одного примера. Эта библиотека предоставляет набор примитивов, таких как async/await и каналов, которые обычно запекаются на других языках программирования. Он также поддерживает легкие актеры без будущего. Вы можете прочитать больше в Руководстве по kotlinx.coroutines на примере.

Каналы, предоставляемые kotlinx.coroutines могут заменять или увеличивать Rx в определенных случаях использования. Существует отдельное руководство по реактивным потокам с сопрограммами, которое углубляется в сходства и различия с Rx.

Ответ 3

В разговоре/документе вы не говорите о каналах. Каналы - это то, что заполняет пробел между вашим текущим пониманием сопрограмм и программированием, управляемым событиями.

С сопрограммами и каналами вы можете программировать на основе событий, так как вы, вероятно, привыкли делать с rx, но можете сделать это с помощью синхронного кода и без так много "настраиваемых" операторов.

Если вы хотите это лучше понять, я предлагаю посмотреть вне котлина, где эти концепции более зрелые и утонченные (не экспериментальные). Посмотрите core.async из Clojure, видеоролики Rich Hickey, сообщения и связанные с ними обсуждения.

Ответ 4

сопрограммы в тысячи раз лучше, забудьте RX !!!!