Comments 28
Я бы перевёл to grok как «раздуплять» =)
-4
Слово to grok изобретено Хайнлайном и имеет два смысла: 1) понять во всей максимально возможной полноте и 2) съесть (по сюжету романа эти два значения связаны между собой). Так что переводчики романа (равно как и вы) поступили совершенно правильно, изобретя аналогичное слово для русского языка.
+9
«Прохавать» )
+1
В русском "поведать" и "отведать" — так же весьма близкие, однокоренные слова...
0
Отличная статья, благодарю! Вот только один маленький нюанс — почему нигде не используется более краткая запись для лямбд — указатели на методы? С ними было бы ещё компактней и даже читабельней, как по мне...
0
Последнее время много слышу про Reactive и т.д.
А вот в чем отличие от Java 8 Streams? Все ваши примеры в статье можно заменить на Streams.
А вот в чем отличие от Java 8 Streams? Все ваши примеры в статье можно заменить на Streams.
+2
Java 8 Streams работают с Iterable, то есть Streams сами вытягивают данные, Pull API. В то время как в Rx (RxJava) Observable сам уведомляет о следующем событии (ошибка, новый элемент или конец потока), то есть это Push API.
Кроме того, Rx — это больше про бизнес логику, обработку данных, переключение между потоками и вот это всё, в то время как Streams это про функциональные операции над коллекциями/потоками данных.
Скажем, попробуйте с помощью Streams сделать такую вещь: сетевой запрос, который сначала вернёт локальный кеш (если он есть), потом сходит в сеть, вернёт результат из сети (и положит его в кеш), причём всё это на бэкграунд потоке(ах), а слушатель на UI потоке + обработка ошибок. Я не спорю, что это можно сделать на Streams с такой-то матерью, но Rx для подобных вещей гораздо удобнее.
Кроме того, Rx — это больше про бизнес логику, обработку данных, переключение между потоками и вот это всё, в то время как Streams это про функциональные операции над коллекциями/потоками данных.
Скажем, попробуйте с помощью Streams сделать такую вещь: сетевой запрос, который сначала вернёт локальный кеш (если он есть), потом сходит в сеть, вернёт результат из сети (и положит его в кеш), причём всё это на бэкграунд потоке(ах), а слушатель на UI потоке + обработка ошибок. Я не спорю, что это можно сделать на Streams с такой-то матерью, но Rx для подобных вещей гораздо удобнее.
+9
Помимо вышеперечисленного:
Для Android нет Java 8 и ее Streams, даже если использовать Retrolambda.
Еще для Android есть RxBinding либы для различных виджетов, которые так же дают много вкусняшек и завязаны на RxJava.
Для Android нет Java 8 и ее Streams, даже если использовать Retrolambda.
Еще для Android есть RxBinding либы для различных виджетов, которые так же дают много вкусняшек и завязаны на RxJava.
+3
Я использую этот проект как стрим на андройде github.com/aNNiMON/Lightweight-Stream-API. Но он конечно не исключает rx.
+2
Может конечно придираюсь, но
> Задача этого цикла статей состоит не в том, чтобы объяснить всё вплоть до последней запятой (вряд ли я смог бы это сделать), но, скорее в том, чтобы заинтересовать вас RxJava, и тем, как она работает.
И сразу понеслись примеры кода…
А где объяснение, что это вообще такое ваш RxJava и для чего его придумали?
> Задача этого цикла статей состоит не в том, чтобы объяснить всё вплоть до последней запятой (вряд ли я смог бы это сделать), но, скорее в том, чтобы заинтересовать вас RxJava, и тем, как она работает.
И сразу понеслись примеры кода…
А где объяснение, что это вообще такое ваш RxJava и для чего его придумали?
0
Придумали для того чтоб реалзовать парадигму реактивного программирования.
Суть — передавать события по цепочке со всевозможными трансформациями по пути. Абстрактный пример — представте таблицу Excel. Вы изменили ячейку — это начальное событие. Но от этой ячейки зависит значение других ячеек — они слушают событие от первой ячейки, применяют его и рассылают событие что они изменились. У них так же могут быть слушатели… Это простой пример реализации реактивного программирования.
Суть — передавать события по цепочке со всевозможными трансформациями по пути. Абстрактный пример — представте таблицу Excel. Вы изменили ячейку — это начальное событие. Но от этой ячейки зависит значение других ячеек — они слушают событие от первой ячейки, применяют его и рассылают событие что они изменились. У них так же могут быть слушатели… Это простой пример реализации реактивного программирования.
+3
Многопоточное приложение — что будет, после того, как в 1-й ячейке изменились данные и информация была реактивно передана дальше и, что будет, если в момент реактивного изменения второй ячейки, произойдет изменение данных в 1-ой? Будет новая итерация всей системы и зачем это нужно? Или, чем закончится изменение 3-й ячейки в 1-й итерации, если данные уже изменились? Может быть лучше применить шину данных (Otto, к примеру), где все слушатели получают актуальные, в настоящий момент, данные, не зависимо от состояния системы в целом.
0
Нет никаких ячеек :)
Для таких случаев есть операторы, которые позволяют обрабатывать группы событий: Debounce, Window, Buffer и тд.
Event bus тут ничем не отличается, собственно, Observable (PublishSubject) может заменить Event Bus полностью.
Для таких случаев есть операторы, которые позволяют обрабатывать группы событий: Debounce, Window, Buffer и тд.
Event bus тут ничем не отличается, собственно, Observable (PublishSubject) может заменить Event Bus полностью.
+2
Ячейки — ответ на пост MercurieVV.
0
Группа событий — это аналог транзакций? Могу ли я получить ответ на свой вопрос? Вы готовы ответить, что будет, если данные изменятся динамически в другом потоке? Как RxJava это регламентирует?
Исходя из простого примера с ячейками в ехеl.
Исходя из простого примера с ячейками в ехеl.
+1
Группа событий — это аналог транзакций?
Nope. Смотрите, в Rx (да и не только) есть такое понятие — Backpressure. Это когда у вас поток событий большой и они поступают быстрее, чем вы их обрабатываете. Для борьбы с Backpressure или просто для утихомиривания резкого потока событий в Rx есть несколько полезных операторов:
Debounce — скажем, пользователь вводит текст в поле, вы на это шлёте запросы в сеть, но вы не хотите на каждый символ этого делать если пользователь быстро вводит текст, тогда Debounce ваш друг — вы указываете временное окно, скажем, 300 мс и Debounce вернет вам результат только если после последнего события прошло 300 мс, то есть вы отфильтруете частые нажатия.
Filter — простейший оператор, в котором вы можете по какой-то вашей логике пропускать часть событий.
Buffer — оператор, которому вы говорите, а группируй мне события по 10 штук (или сколько нужно) и отправляй списком, а не по отдельности.
Window — похож на Buffer, но группирует события по временному промежутку, скажем, 500 мс, etc.
И тд., всякие OnBackpressureDrop, etc, очень рекомендую посмотреть документацию с прекрасными иллюстрациями: reactivex.io
+2
Могу ли я получить ответ на свой вопрос?
Да :)
Вы готовы ответить, что будет, если данные изменятся динамически в другом потоке?
Готов :)
Как RxJava это регламентирует?
Как напишите, так и будет работать, зависит от примененных операторов. Вы можете добиться любого нужного вам поведения, причём, довольно элегантно.
Нужно отреагировать на все события — реагируйте, нужно пропустить близкие по времени события или сгруппировать и обработать их пачкой — пожалуйста, все возможности Rx перед вами, нужно лишь понять и прочитать документацию: reactivex.io
P.S.
Кстати, приходите на Yandex Mobile Camp 12 сентября (суббота) в Москве или на трансляцию в Новосибирске или Нижнем Новгороде, поговорим про Rx events.yandex.ru/events/yamobcamp :)
+1
Во первых, хочу отметить что пример с Экселем — абстрактный пример что такое реактивное программирование, а не как работает rxJava
0
Ну а если говорить о rxJava, то ее суть — шина/цепочка/pipeline событий. Очень желательно чтоб передаваемые данные были immutable, иначе вся ответственность за его изменения ложится на вас.
Возьмем ваш пример применительно к rxJava.
Простейшая реализация:
Такт 1) Ячейка (испускатель событий) 1, испускает событие со своим новым значением.
Такт 2) Оно попадает в ячейку 2. Она его обрабатывает. В момент обработки, ячейка 1 испускает новый объект данных.
Такт 3) В ячейку 2 приходят новые данные. Она их обрабатывает.
Реализация с backpressure buffer:
Такт 1) Ячейка (испускатель событий) 1, испускает событие со своим новым значением. Буффер ловит его и держит у себя не отпуская дальше.
Такт 2) Я1 испускает новое событие. Буффер опять его ловит.
… какое-то время спустя
Такт N) Буффер все накопленные событие кладет в список и передает его как список в Я2
У rxJava очень наглядные картинки по каждому оператору. Посмотрите например
на debounce (раскройте там список rxJava в language specific) reactivex.io/documentation/operators/debounce.html#collapseRxJava
и group reactivex.io/documentation/operators/buffer.html
Возьмем ваш пример применительно к rxJava.
Простейшая реализация:
Такт 1) Ячейка (испускатель событий) 1, испускает событие со своим новым значением.
Такт 2) Оно попадает в ячейку 2. Она его обрабатывает. В момент обработки, ячейка 1 испускает новый объект данных.
Такт 3) В ячейку 2 приходят новые данные. Она их обрабатывает.
Реализация с backpressure buffer:
Такт 1) Ячейка (испускатель событий) 1, испускает событие со своим новым значением. Буффер ловит его и держит у себя не отпуская дальше.
Такт 2) Я1 испускает новое событие. Буффер опять его ловит.
… какое-то время спустя
Такт N) Буффер все накопленные событие кладет в список и передает его как список в Я2
У rxJava очень наглядные картинки по каждому оператору. Посмотрите например
на debounce (раскройте там список rxJava в language specific) reactivex.io/documentation/operators/debounce.html#collapseRxJava
и group reactivex.io/documentation/operators/buffer.html
+1
Интересно, насколько близка эта концепция к "сигналам-слотам" на Qt. Спасибо за статью.
0
Части 2-4 — оригинал, на английском:
blog.danlew.net/2014/09/22/grokking-rxjava-part-2
blog.danlew.net/2014/09/30/grokking-rxjava-part-3
blog.danlew.net/2014/10/08/grokking-rxjava-part-4
blog.danlew.net/2014/09/22/grokking-rxjava-part-2
blog.danlew.net/2014/09/30/grokking-rxjava-part-3
blog.danlew.net/2014/10/08/grokking-rxjava-part-4
+1
Отличная статья, спасибо за перевод!
0
Sign up to leave a comment.
Грокаем* RxJava, часть первая: основы