Реактивные
расширения для JavaScript...
...и пусть события сами идут
Где мы используем
события?
ВЕЗДЕ
Что не так с событиями?
● как компоновать?
● как фильтровать?
● как собирать данные от разных событий?
● как не сойти с ум...
О ужасный callback!
$('#some-element').animate({
width: 100,
height: 50
}, {
duration: 300,
complete: function() {
// Step...
О ужасный callback!
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(valu...
О ужасный callback! (и доступ к данным)
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(...
Варианты решения а-ля promise...
Q.fcall(step1)
.then(step2)
.then(step3)
.then(step4)
.then(function (value4) {
// Do som...
...или настоящими promise
function successFunc(){ console.log( “success!” ); }
function failureFunc(){ console.log( “failu...
Reactive Extensions for
JS
...is a library to compose asynchronous and
event-based programs using observable
collections a...
Реактивные
расширения
...библиотека для создания асинхронных и
основанных на событиях программ
используя наблюдаемые колле...
Состав RxJS:
● объекты для представления асинхронных
потоков данных
● операторы для создания, фильтрации и
управления подо...
Реактивное программирование
- парадигма, ориентированная на потоки данных и
распространение изменений.
Это означает, что д...
2 примера реактивности из жизни
1. Excel 2. Ищем работу:
обзванивать
вакансииpull vs
разместить резюме
ждать звонков
push
Основа идеологии
Наблюдатель
Observer
Наблюдаемое
(поток)
Observable
подписывается (subscribe) ⇒
⇐ присылает сообщения (on...
Наблюдаемая последовательнсть
RxJS против не-RxJS
$('button').clickAsObservable
()
.skip(2)
.take(2)
.timeInterval()
.doAction(flickerButton)
.subscribe...
query
Используем привычные функции
Array
● concat
● every
● filter
● map
● reduce
● some
● forEach
Observable
● concat
● a...
Поддержка родных событий jQuery
•bind - bindAsObservable
•delegate - delegateAsObservable
•live - liveAsObservable
•on - o...
Мышь и клавиатура
•change - changeAsObservable
•click - clickAsObservable
•dblclick - dblclickAsObservable
•focus - focusA...
Ajax и анимация
• ajax - ajaxAsObservable
• get - getAsObservable
• getJSON - getJSONAsObservable
• getScript - getScriptA...
Состав RxJS:
● объекты для представления асинхронных
потоков данных
● операторы для создания, фильтрации и
управления подо...
Операторы объединения
● Amb
● Merge
● Concat
● CombineLatest
● Zip
● Repeat
stream y
stream x
result
result = fn(x, y, …, ...
Операторы фильтрации и выбора
● where (filter) / whereTrue / whereFalse
● take / takeUntil / takeWhile
● skip / skipUntill...
Операторы для данных
● scan
● count
● min
● max
● groupBy
● distinct / distinctUntilChanged
● throttle
Временные диаграммы
Временные диаграммы вживую
j q u
t
result = source.throttle(1500)
j qu jqu
source
result
jqu
jque
jque
1,5 сек 1,5 сек
0,3 сек
.select()
negativeStream =
stream.select(function(value) { return -value });
negativeStream = stream.select(invert);
funct...
.where()
negativeStream = stream
.where(function(value) { return value % 2 == 0 });
negativeStream = stream.where(isEven);
xStream.merge(yStream)
xStream.combineLatest(yStream)
x.zip(y)
.bufferWithTime(3000)
.bufferWithCount(3)
.bufferWithTimeOrCount(3000, 3)
dots.delay(1000)
Операторы - over 9000
aggregate
all
amb
and
any
asObservable
average
buffer
bufferWithCount
bufferWithTime
bufferWithTimeO...
Языки с библиотеками RX
1. node.js
2. Java
3. Ruby
4. Python
5. ObjectiveC
6. C++
7. ...
8. https://github.com/Reactive-Ex...
Демо
закрепим в jsFiddle полученные знания
Большое приложение
основанное на RxJS
selectedItem =>
{id: 1, title: “Матрешка”}
loadPanelStatus =>
{status: true}
pageSelection =>
{page: 4}
loadPanelStatus =>...
Модуль
корзины
Модуль
каталога
Контролер
couponChanges
.selectPropert(‘id’) => {id: “couponId”} => “couponId”
.select(affe...
Вредные советы
● одноразовые потоки
● потоки-сироты
● превращаем все события в потоки, все!
● общие названия потоков (data...
Полезные советы
● простые данные в сообщениях
● говорящие названия для потоков
● простая логика для объединения
● промежут...
Фото кода
Литература:
1. http://www.introtorx.com/Content/v1.0.10621.0/00_Foreword.html
2. https://github.com/Reactive-Extensions
3....
Спасибо!
Виктор Русакович из Минска, Беларусь
nemiga@gmail.com
Вопросы?
Upcoming SlideShare
Loading in …5
×

Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, Русакович Виктор

488 views

Published on

Виктор Русакович, Минск, Web-developer c 6-ти летним опытом разработки, компания GP Software.travel

«Реактивный JavaScript. Победа над асинхронностью и вложенностью». Development секция. Для разработчиков. Высокий уровень подготовки.
«Непрерывная интеграция сложного проекта. Кто всё сломал?». IT секция. Agile отделение. Для всех уровней подготовки.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
488
On SlideShare
0
From Embeds
0
Number of Embeds
64
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, Русакович Виктор

  1. 1. Реактивные расширения для JavaScript... ...и пусть события сами идут
  2. 2. Где мы используем события? ВЕЗДЕ
  3. 3. Что не так с событиями? ● как компоновать? ● как фильтровать? ● как собирать данные от разных событий? ● как не сойти с ума от асинхронности? ● как не строить Пирамиды Обратных Вызовов? ● … (еще примерно 42 пункта)
  4. 4. О ужасный callback! $('#some-element').animate({ width: 100, height: 50 }, { duration: 300, complete: function() { // Step 2: $('#another-element').fadeOut(300, function() { // Step 3: setTimeout(function() { // Step 4: $.ajax({ url: 'http://google.com', }).done(function() { // Step 5: setTimeout(function() { // Step 6: $('#third-element').remove(); }, 250); }); }, 300); }); } });
  5. 5. О ужасный callback! step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
  6. 6. О ужасный callback! (и доступ к данным) step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { if (value2 === 4) return null step4(value3, function(value4) { if (value2 > value3) work() }); }); }); });
  7. 7. Варианты решения а-ля promise... Q.fcall(step1) .then(step2) .then(step3) .then(step4) .then(function (value4) { // Do something with value4 }) .done(); https://github.com/kriskowal/q/ A tool for making and composing asynchronous promises in JavaScript (282 362 forks at Github).
  8. 8. ...или настоящими promise function successFunc(){ console.log( “success!” ); } function failureFunc(){ console.log( “failure!” ); } $.when( $.ajax("/main.php" ), $.ajax("/modules.php" ), $.ajax(“/lists.php” ) ).then( successFunc, failureFunc ); Все равно не хватает контроля над данными!
  9. 9. Reactive Extensions for JS ...is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.
  10. 10. Реактивные расширения ...библиотека для создания асинхронных и основанных на событиях программ используя наблюдаемые коллекции и LINQ операторы.
  11. 11. Состав RxJS: ● объекты для представления асинхронных потоков данных ● операторы для создания, фильтрации и управления подобными объектами и данными внутри них ● немного магии
  12. 12. Реактивное программирование - парадигма, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что выполняемая модель должна автоматически распространять изменения сквозь поток данных.
  13. 13. 2 примера реактивности из жизни 1. Excel 2. Ищем работу: обзванивать вакансииpull vs разместить резюме ждать звонков push
  14. 14. Основа идеологии Наблюдатель Observer Наблюдаемое (поток) Observable подписывается (subscribe) ⇒ ⇐ присылает сообщения (onNext)
  15. 15. Наблюдаемая последовательнсть
  16. 16. RxJS против не-RxJS $('button').clickAsObservable () .skip(2) .take(2) .timeInterval() .doAction(flickerButton) .subscribe(logClicks) var i= 0, lastTs = new Date(), nowTs $('button').click(function(){ i++; if (i<=2 || i>=4) return nowTs = new Date() flickerButton() logClicks(diff(lastTs, nowTs)) })
  17. 17. query Используем привычные функции Array ● concat ● every ● filter ● map ● reduce ● some ● forEach Observable ● concat ● all ● where ● select ● aggregate ● any ● subscribe
  18. 18. Поддержка родных событий jQuery •bind - bindAsObservable •delegate - delegateAsObservable •live - liveAsObservable •on - onAsObservable •$.Deferred.toObservable / Rx.Observable.toDeferred
  19. 19. Мышь и клавиатура •change - changeAsObservable •click - clickAsObservable •dblclick - dblclickAsObservable •focus - focusAsObservable •focusin - focusinAsObservable •focusout - focusoutAsObservable •hover - hoverAsObservable •keydown - keydownAsObservable •keypress - keypressAsObservable •keyup - keyupAsObservable •load - loadAsObservable •mousedown - mousedownAsObservable •mouseenter - mouseenterAsObservable •mouseleave - mouseleaveAsObservable •mousemove - mousemoveAsObservable •mouseout - mouseoutAsObservable •mouseenter - mouseenterAsObservable •mouseleave - mouseleaveAsObservable •mousemove - mousemoveAsObservable •mouseout - mouseoutAsObservable
  20. 20. Ajax и анимация • ajax - ajaxAsObservable • get - getAsObservable • getJSON - getJSONAsObservable • getScript - getScriptAsObservable • post - postAsObservable • animate - animateAsObservable • fadeIn - fadeInAsObservable • fadeOut - fadeOutAsObservable • fadeTo - fadeToAsObservable • fadeToggle - fadeToggleAsObservable • hide - hideAsObservable • show - showAsObservable • slideDown - slideDownAsObservable • slideToggle - slideToggleAsObservable • slideUp - slideUpAsObservable
  21. 21. Состав RxJS: ● объекты для представления асинхронных потоков данных ● операторы для создания, фильтрации и управления подобными объектами и данными внутри них ● немного магии
  22. 22. Операторы объединения ● Amb ● Merge ● Concat ● CombineLatest ● Zip ● Repeat stream y stream x result result = fn(x, y, …, n)
  23. 23. Операторы фильтрации и выбора ● where (filter) / whereTrue / whereFalse ● take / takeUntil / takeWhile ● skip / skipUntill / skipWhile ● select (map) / selectMany / selectProperty stream x result result = fn.apply(x)
  24. 24. Операторы для данных ● scan ● count ● min ● max ● groupBy ● distinct / distinctUntilChanged ● throttle
  25. 25. Временные диаграммы
  26. 26. Временные диаграммы вживую j q u t
  27. 27. result = source.throttle(1500) j qu jqu source result jqu jque jque 1,5 сек 1,5 сек 0,3 сек
  28. 28. .select() negativeStream = stream.select(function(value) { return -value }); negativeStream = stream.select(invert); function invert(value) { return -value });
  29. 29. .where() negativeStream = stream .where(function(value) { return value % 2 == 0 }); negativeStream = stream.where(isEven);
  30. 30. xStream.merge(yStream)
  31. 31. xStream.combineLatest(yStream)
  32. 32. x.zip(y)
  33. 33. .bufferWithTime(3000) .bufferWithCount(3) .bufferWithTimeOrCount(3000, 3)
  34. 34. dots.delay(1000)
  35. 35. Операторы - over 9000 aggregate all amb and any asObservable average buffer bufferWithCount bufferWithTime bufferWithTimeOrCount case | switchCase catch | catchException catch | catchException combineLatest concat connect contains count create createWithDisposable defaultIfEmpty defer delay delayWithSelector dematerialize distinct distinctUntilChanged do | doAction doWhile elementAt elementAtOrDefault empty every expand filter finally | finallyAction find findIndex first firstOrDefault flatMap flatMapLatest for | forIn forkJoin fromArray generate generateWithAbsoluteTime generateWithRelativeTime groupBy groupByUntil groupJoin if | ifThen ignoreElements interval isEmpty join last lastOrDefault manySelect map max maxBy merge mergeObservable min minBy multicast never observeOn onErrorResumeNext onErrorResumeNext pluck publish publishLast publishValue range reduce refCount repeat repeat replay retry return | returnValue sample scan select selectMany selectSwitch single singleOrDefault skip skipLast skipLastWithTime skipUntil skipWhile some start startWith subscribe subscribeOn sum switch | switchLatest take takeLast takeLastBuffer takeLastBufferWithTime takeLastWithTime takeUntil takeWhile throttle throttleWithSelector throw | throwException timeInterval timeout timeoutWithSelector timer timestamp toArray toAsync using when where while | whileDo window windowWithCount windowWithTime windowWithTimeOrCount zip
  36. 36. Языки с библиотеками RX 1. node.js 2. Java 3. Ruby 4. Python 5. ObjectiveC 6. C++ 7. ... 8. https://github.com/Reactive-Extensions
  37. 37. Демо закрепим в jsFiddle полученные знания
  38. 38. Большое приложение основанное на RxJS
  39. 39. selectedItem => {id: 1, title: “Матрешка”} loadPanelStatus => {status: true} pageSelection => {page: 4} loadPanelStatus => {status: true} couponChanges => {id: undefined} itemRemoval => {id: 1} Модуль корзины Модуль каталога КонтролерselectedItem {id: 1} selectedItem loadPanelStatus couponChanges itemRemoval input streams itemRemoval {id: 2}
  40. 40. Модуль корзины Модуль каталога Контролер couponChanges .selectPropert(‘id’) => {id: “couponId”} => “couponId” .select(affectedItems) => “couponId” => [1,2,4] .subscribe(updateItemsPrice) itemRemoval .skipUntil(loadPanelStatus.whereTrue()) .takeUntil(loadPanelStatus.whereFalse()) .subscribe(markItemAsRemoved) <= {id: 1} function affectedItems(coupon) { return $(‘.items.’+coupon).map(function(item){ return $(item).data(‘id’) }) } selectedItem {id: 1} selectedItem loadPanelStatus couponChanges itemRemoval input streams itemRemoval {id: 2}
  41. 41. Вредные советы ● одноразовые потоки ● потоки-сироты ● превращаем все события в потоки, все! ● общие названия потоков (dataStream) ● свои операторы не читая документацию
  42. 42. Полезные советы ● простые данные в сообщениях ● говорящие названия для потоков ● простая логика для объединения ● промежуточные потоки ● функциональный подход
  43. 43. Фото кода
  44. 44. Литература: 1. http://www.introtorx.com/Content/v1.0.10621.0/00_Foreword.html 2. https://github.com/Reactive-Extensions 3. https://github.com/Reactive-Extensions/RxJS/tree/master/doc 4. http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/02/25/rx-for-beginners-toc.aspx 5. http://www.slideshare.net/mattpodwysocki/cascadiajs-dont-cross-the-streams 6. http://www.slideshare.net/panesofglass/rx-workshop 7. http://www.infoq.com/reactive-extensions/ 8. http://mywebbasedcomputer.com/users/johngslater/tech/rx/bubbleDiagrams.html 9. https://github.com/Netflix/RxJava/wiki/Observable-Utility-Operators 10. Matthew Podwysocki
  45. 45. Спасибо! Виктор Русакович из Минска, Беларусь nemiga@gmail.com
  46. 46. Вопросы?

×