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

27

Почему я хочу использовать сопрограммы Kotlin?

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

Я основываю свое мнение на сопрограмме на этом обсуждении дизайна Андреем Бреславом (JetBrains): Ссылка

Слайд-шоу из разговора доступно здесь: Ссылка

    
задан charlie_pl 06.02.2017 в 11:55
источник
  • Лучший источник текущего состояния сопрограмм: github.com/Kotlin/kotlin-coroutines/blob/master/... –  hotkey 06.02.2017 в 14:07

3 ответа

28

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

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

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

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

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

Coroutines лучше справляться с ресурсами

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

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

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

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

    
ответ дан Geoffrey Marizy 09.02.2017 в 03:00
  • Итак, вместо того, чтобы обернуть все в Observable, вы обернете все в Будущее. –  IRus 10.02.2017 в 23:23
  • К счастью, сопрограммы Kotlin довольно не похожи на C # и JS и не требуют упаковки вашего кода в Будущее. Вы можете использовать фьючерсы с сопрограммами Kotlin, но идиоматический код, основанный на сопроводительных материалах Kotlin, почти не использует фьючерсов. –  Roman Elizarov 26.03.2017 в 18:02
  • Архитектуру, управляемую событиями, можно легко использовать с помощью каналов. –  pablisco 17.10.2017 в 00:25
44

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

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

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

Более подходящим является сравнение Rx с некоторыми конкретными библиотеками, которые реализованы на основе сопрограмм Kotlin.

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

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

ответ дан Roman Elizarov 04.05.2017 в 14:42
3

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

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

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

ответ дан Davide Bertola 11.11.2017 в 08:07