The State of Reactive in JS: практический обзор FRP библиотек
Статья родилась из этого ответа на StackOverflow и переросла в этот блог пост (на английском), но я думаю она не утратила актуальность.
Это своего рода эталон — появление Reactive Extensions для .net, в каком-то смысле, создало эту дисциплину.
Когда-то модная библиотека для хипстеров — сейчас все забыли
Библиотека от caolan — автора async
Из-за отстутсвия вменяемых примеров вам прийдется посмотреть все эти библиотеки, Rx* так точно. ИМХО, самая правильная Highland — люди, которые ее писали, понимают идиоматику платформы и любят ее. Самая «зрелая» RxJS — ее еще в Angular «впилили», hype-гарантирован.
Сейчас очень много шума вокруг Reactive Programming. Я потратил какое-то время на изучение этой дисциплины применимо к JavaScript и Node.js и сложил свое мнение о самых, на мой взгляд, интересных библиотеках.
RxJS
Это своего рода эталон — появление Reactive Extensions для .net, в каком-то смысле, создало эту дисциплину.
Pros:
- Документация и большое коммьюнити (>15000 звездочек на Github,>3073 тэгов на SO);
- Это библиотека из семейства Rx*, а значит использует тот же интерфейс. Практически, это значит что иногда можно смотреть примеры из RxJava и оригинально Reactive Extensions;
- Есть примитивы почти на все случаи жизни;
- Есть backpressure (вот тут можно прочитать что это);
- по этой библиотеке есть одна книга.
Cons:
- Иногда выглядит как «матан». Документации напоминают бездну — не понятно, как это все «на голову натянуть»?
- Реализовано ребятами с Java`ой в голове (любовь к большому количеству абстракций, идиоматика из Java/.Net, иногда странные сигнатуры). Это не то чтобы плохо, просто некоторые вещи смотрятся в JS странными (пример Scheduler — я так и не понял зачем это все нужно в single-thread среде). Отсюда же желание писать на TypeScript`e
Bacon.js
Когда-то модная библиотека для хипстеров — сейчас все забыли
Pros
- Хорошая документация и хорошие примеры от комьюнити (например, игра Змейка);
- Реализованы почти все примитивы из Rx*;
- Реализовывали в первую очень для JS и JSсным бэкграундом;
- ИМХО, очень легко начать просто пройдясь по примерам и документации.
Cons
- Нет Backpressure — давайте просто забудем про backend разработку
Highland.js
Библиотека от caolan — автора async
Pros:
- Сразу писалось для JS/Node.js ребятами которые на них писали что-то большое и любят язык/платформу –, а значит JS-ная идиоматика и Node.js в голове (см. следующий пункт);
- Построенно поверх Node.js Stream, это обеспечело библиотеке маленький размер. Кроме того, субъективно, так намного легче про это все думать: у нас есть stream A, мы с ним что-то делаем и pipe`аем его в stream B (вот моя статья, с примером);
- backpressure — Причем насколько я понимаю ничего не нужно было писать руками, все уже есть в Node.js Stream.
Cons:
- Слабая документацияуже получше и отсутсвие примеров. За примерами прийдется лезть в Rx или Bacon — смиритесь с этим;
- Отсутсвие многих примитивов. Не то чтобы их сложно реализовать руками, но все же. Пример .interval и .combineLatest;
- Очень субъективно: Флегматичное коммьюниты — сами пишут, сами кайфуют, экспансии не ведут.
Вместо итога
Из-за отстутсвия вменяемых примеров вам прийдется посмотреть все эти библиотеки, Rx* так точно. ИМХО, самая правильная Highland — люди, которые ее писали, понимают идиоматику платформы и любят ее. Самая «зрелая» RxJS — ее еще в Angular «впилили», hype-гарантирован.
Подсказка: Если вам нужно что-то спросить на StackOverflow — переводите сразу RxJS-«диалект», так с большей вероятностью ответят.
Комментарии (2)
4 апреля 2017 в 17:33 (комментарий был изменён)
0↑
↓
Все эти вещи примитивны, ничего нет как было написано (матан) и все такое. Rx это вывернутый итератор грубо говоря это (o => ({o (10); o (20)}))(x => console.log (x)) просто на это натянули классы, много шума, но если понимать это на примитивах типа функций то https://github.com/xgrommx/from-combinators-to-fp/blob/master/src/frp/reactive.js. Идея дуализма https://jsbin.com/bihoke/2/edit? html, js, console https://github.com/xgrommx/from-combinators-to-fp/blob/master/src/frp/duality.js
В плане доки, да для 5 версии она уродская, для 4 я когда-то сделал это http://xgrommx.github.io/rx-book (когда у Rx с этим были большие проблемы)
Bacon появился потому что автору было не понятно идея холодных, горячих, подогретых обзерваблов (хотя его идея мне тоже нравится)
MostJs — офигенный пример как надо делать вещи нацеленные на перформанс (быстрее его пока нет) также у него идея почти полность FP принципы и не зря это расшифровывается как Monadic Streams
Также есть интерсные вещи типа https://github.com/paldepind/flyd или https://github.com/funkia/hareactive
https://github.com/staltz/xstream идея которого только горячие обзерваблы
И еще много чего http://xgrommx.github.io/rx-book/content/resources/reactive_libraries/index.html#libraries
Да и вообще обернувши Either (монаду) в асинхронную обертку можно даже такое делатьhttps://github.com/xgrommx/practical-functional-programming/blob/master/stream.js
Я много еще чего не привел тут, ну много можно найти в моей книге (там много чего есть в разделе Resources)
Плюс для Rx я сделал https://jsbin.com/migogu/1/edit? js, output когда надо нужно объяснить как это работает (помимо http://rxmarbles.com/)
Еще забыл упомянуть про одну классную фичу в Bacon и частично сделанную в Rx — это join pattern (update в Bacon и в Rx это можно сделать через when)4 апреля 2017 в 17:38
0↑
↓
Вот как это можно сделать в Rx https://github.com/xgrommx/react-rx-flux/blob/master/src/rx-extensions.js#L37
Еще этот же варинт в most.js (у этой либы нет when поэтому такая версия) https://github.com/xgrommx/most-reactive-flux/blob/master/app/src/utils.js#L8 (кстати так же можно сделать в Rx)
Еще в Rx очень много операторов могут быть выражены через малый базис https://gist.github.com/xgrommx/1aec6c7e47757799a7695ba08a9541ee
Ну и еще для стримов нет границ : D