webcamp:front-end developers day. Роман Якобчук "frp + react, building async...
TRANSCRIPT
Що таке FRP“Functional reactive programming (FRP) is a programming paradigm for
reactive programming (asynchronous dataflow programming) using the
building blocks of functional programming (e.g.map, reduce, filter)"
Wikipedia
Серйозно?
“2
Reactive programminghttp://www.reactivemanifesto.org/
b = c = 1
a = b + c # => 2
c = 4
a # ?
01.
02.
03.
04.
3
Reactive programming
4
Reactive programming• Imperative (Angular, Ember, Backbone)
• Functional (Bacon, Rx.js, Kefir)
• OOP # ?!
5
Reactive programming• Imperative (Angular, Ember, Backbone)
• Functional (Bacon, Rx.js, Kefir)
• OOP # ?!
6
Functional programming• Функція - об’єкт першого класу(first class citizen)
• Відсутність сайд-ефектів(використання чистих функцій)
• Іммутабельні данні
7
Як виглядає FP кодvar topAds = tests
.map(...)
.reduce(...)
.filter(...)
.sort(...)
.slice(0,6)
01.
02.
03.
04.
05.
06.
8
Коли використовувати FRP• багато залежних станів
• є декілька джерел надходження сигналів
• є жорстка асинхронність
9
Коли НЕ використовувати FRP• ви працюєте з данними що рідко змінюються
• в команді не нема кому підтримувати
• це явний оверхед
10
Що треба пам'ятати про FRP• Все зберігається в стрімах
• Все іммутабельно
11
Бібліотеки JS• Bacon.js
• RxJS
• Kefir.js
• Scala.js
12
Code Samplesvar targetText = Bacon
.fromEventTarget(document, 'mousemove')
.filter(targetContainsText)
.map(getTextFromEvent)
.skipDuplicates();
01.
02.
03.
04.
05.
13
АсинхронністьЧи відноситься остання відповідь до останнього запиту?
var responses = targetText
.flatMapLatest(postText);
responses.onValue(processResponse);
01.
02.
03.
14
Додаємо джерело подійvar buttonPresses = buttons
.asEventStream('click')
.map(processButtonClick);
var responses = targetText
.merge(buttonPresses)
.flatMapLatest(postText);
01.
02.
03.
04.
05.
06.
15
Де результат?• Перетворили події в данні
• Налаштували потоки цих данних
• Що б не сталось, ми завжди маємо актуальний стан
• Як відобразити це в нашому UI?
16
ReactProps State
поточний стан компонента
“Every time your data changes, it’s like hitting refresh in a server rendered
app.”
Pete Hunt, Facebook
17
Архітектура БандуриView
• Сам плеєр
• Progress-bar
• Volume-bar
18
Архітектура БандуриAction
• UI
• Внутрішні івенти(елементи логіки)
• Обогртка для розробників
• Дистанційне керуваня(веб-сокет)
• Пряме підключення до стрімів
19
Dispatcher/StoredispatcherAPI =
collections : new Bacon.Bus()
...
#-------------
playlistsCollection = collections
.scan(new PLCollection(), (collection, ev) ->
collection[ev.action](ev.playlist)
...
01.
02.
03.
04.
05.
06.
07.
08.
20
Оновлюємо ViewplaylistsCollection.onValue (PLC) ->
UI.player.setProps PLCollection: PLC
UI.progressbar.setProps currentTrack: ...
01.
02.
03.
21
Додамо джерело сигналуremoteActions = Bacon.fromEventTarget ws , 'message', ...
controls.plug(remoteActions)
01.
02.
22
Це страшне слово "монада"monad
.map(...)
.reduce(...)
01.
02.
03.
23
Підозріло схоже на масив?• Так, масив це теж монада
• Так, всі ці "потоки" це теж монади
• Так, саме тому ви можете уявити їх як простий масив, останній елемент
якого завжди зберігає актуальний стан
24
Роман Якобчук• http://roma.if.ua
• Skype: r.iakobchuk
• Email: [email protected]
Links
https://github.com/romabelka/jsLab
https://github.com/romabelka/bandura.js
http://www.reactivemanifesto.org
26