SlideShare a Scribd company logo
1 of 93
Download to read offline
Rx.js
making async programming simpler
About me
Mostovenko Alexander
Python developer at
Writing mostly in python and coffeescript.
Love FP stuff.
Traveling, snowboarding, cycling.
https://twitter.com/MostovenkoA
https://github.com/AlexMost
Why Rx.js and not another FRP lib?
● Implemented in a lot of languages
(.NET, Java, Ruby, Python, Clojure, Scala,
Haskell, Objective-C).
● Has a huge amount of docs and examples.
● Why not?
Asynchronous code
Async code in javascript
● Some computation with delayed result.
(data fetch, animations, DOM operations)
● Reacting to events (event handlers)
Sync vs Async dataflow
Synchronous dataflow
Synchronous dataflow
In
Synchronous dataflow
In
1
Synchronous dataflow
In
1
2
Synchronous dataflow
In
1
2
...
Synchronous dataflow
In
1
2
Out
...
Asynchronous dataflow
time
Actions
Asynchronous dataflow (autocomplete)
time
Actions
keyup
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
ajax request
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
ajax request
ajax response
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
ajax request
ajax response
show suggest
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
ajax request
ajax response
show suggest
Asynchronous dataflow (autocomplete)
time
Actions
keyup
per 2 seconds
ajax request
ajax response
show suggest
Ooooops
Problems with async code
1. How to manage async flow in code?
2. How to handle errors?
3. How to compose?
Callbacks
● Event notification
● Manage control flow
Callbacks
● Event notification - Yes
● Manage control flow - Nooooooooooo
Callback hell
async_func1(function(err, data){
async_func2(function(err, data){
async_func3(function(err, data){
async_func4(function(err, data){
});
});
});
});
Callback hell yeah !!!
async_func1(function(err, data){
if (!err) {
async_func2(function(err, data){
if (!err) {
async_func3(function(err, data){
if (!err) {
async_func4(function(err, data){
});
} else {
log(err);
}
});
} else {
log(err);
}
});
} else {
log(err);
}
});
Callback hell yeah !!!
async_func1(function(err, data){
if (!err) {
async_func2(function(err, data){
if (!err) {
async_func3(function(err, data){
if (!err) {
async_func4(function(err, data){
});
} else {
log(err);
}
});
} else {
log(err);
}
});
} else {
log(err);
}
});
UNREADABLE !!!
UNMANAGABLE !!!
UNTESTABLE !!!
UNCOMPOSABLE !!!
PIECE OF ….
CODE
Monad
A monad is just a monoid in the category of
endofunctors
Callback vs Black hole
some_async_func(function(err, result) {
// ... looks like we are in trap
another_wonderful_func(function(err, result){
// ... you are in trap
});
});
Callback vs Black Hole
1. No return value (undefined)
Callback vs Black Hole
1. No return value (undefined)
2. One way ticket (callback hell)
How about Promise?
Promise
var promise = new Promise((resolve, reject) => {
// ... some async staff
});
promise.then(
(result) => {},
(error) => {}
)
Promise
1. Step forward from callbacks for control flow
managing
2. Error handling
Why we should look at Observable?
1. Promise represents only single value.
2. How to cancel?
3. Lazy execution.
4. We can work with Observable as easy as with
promise.
Promise is Observable only with a single value
Observable
The Observable object represents a push
based collection.
Observable
var source = Rx.Observable.create((observer) =>
// some async operation
observer.onNext(data)
// or ..
observer.onError(data)
// or ..
observer.onCompleted(data)
);
source.subscribe(
(data) => {}
(err) => {}
)
Observlable vs promise example
var source = Rx.Observable.create((observer) => {
setTimeout(() => {
console.log("observable timeout hit");
observer.onNext(25);
}, 500);
console.log('observable started')});
source.subscribe(x => console.log(`observable value ${x}`));
Observable
> observable started
> observable timeout hit
> observable value 25
Observlable vs promise example
var promise = new Promise((resolve) => {
setTimeout(() => {
console.log("promise timeout hit");
resolve(25);
}, 500);
console.log("promise started");});
promise.then(x => console.log(`promise value ${x}`));
Promise
> promise started
> promise timeout hit
> promise value 25
Lazy execution
var source = Rx.Observable.create((observer) => {
setTimeout(() => {
console.log("observable timeout hit");
observer.onNext(25);
}, 500);
console.log('observable started')});
// source.subscribe(x => console.log(`observable value ${x}`));
>
Observable can be canceled
var source = Rx.Observable.create((observer) => {
var id = setTimeout(() => {
console.log("observable timeout hit");
observer.onNext(25);
}, 500);
console.log('observable started');
return () => {
console.log("dispose called")
clearTimeout(id);}
});
var disposable = source.subscribe(
x => console.log(`observable value ${x}`));
setTimeout(() => disposable.dispose(), 100)
> observable started
> dispose called
Asynchronous programming landscape
multiple
values
single
value
sync async
a = f(x) a = f(x).then(...)
collection = [1, 2, 3]
a = collection
.filter((v) => v > 2)
Promise
Array
Sync value
?
Asynchronous programming landscape
multiple
values
single
value
sync async
a = f(x) a = f(x).then(...)
collection = [1, 2, 3]
a = collection
.filter((v) => v > 2)
move = Rx.Observable.fromEvent(document, 'mousemove')
my_moves = move
.filter((ev) => ev.clientX > 100)
my_moves.subscribe(...)
Promise
Array
value
Observable
How to create Observable
● Observable.create
● Observable.fromEvent
● Observable.fromNodeCallback
● Observable.fromArray
● Observable.fromPromise
Drag & Drop example
What if i told you ….
That mouse move event is an array and you
can map, filter over it?
var dragTarget = document.getElementById('dragTarget');
// Get the three major events collections
var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup');
var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown');
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
var subscription = mousedrag.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
var dragTarget = document.getElementById('dragTarget');
// Get the three major events collections
var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup');
var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown');
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
var subscription = mousedrag.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
Create observable collections
from DOM events
var dragTarget = document.getElementById('dragTarget');
// Get the three major events collections
var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup');
var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown');
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
var subscription = mousedrag.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
Using power of Rx, combine
existing event streams to produce
mouse drag event collection
var dragTarget = document.getElementById('dragTarget');
// Get the three major events collections
var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup');
var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown');
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
var subscription = mousedrag.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
Subscribe on mouse drag events,
updating top and left attributes
Observable are first class events
Can be:
- passed as a parameter
- returned from a function
- assigned to a variable
Some common basic operations
map
filter
reduce
zip
merge
flatMap
...
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md
map
http://rxmarbles.com/#map
filter
http://rxmarbles.com/#filter
var mousedrag_in_area = mousedrag.filter(({top, left}) => {
return top <= 200 && left <= 200
});
var subscription = mousedrag_in_area.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
let’s filter drag area
delay
http://rxmarbles.com/#delay
let’s create slow mouse drag
var slow_mousedrag = mousedrag.delay(700)
var subscription = slow_mousedrag.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
reduce
http://rxmarbles.com/#reduce
let’s record our drag path
var drag_path = mousedrag
.takeUntil(mouseup)
.reduce(((a, b) => a + `${b.top} ${b.left};`), "")
drag_path.subscribe((path) => pathTarget.innerHTML = path)
flatMap
flatMap
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
flatMap
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
Outer stream
flatMap
var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => {
return mousemove
.map(({clientX: x, clientY: y}) => {
return {left: x - offsetX, top: y - offsetY}})
.takeUntil(mouseup)
});
value as a stream
merge
http://rxmarbles.com/#merge
merge
var btnTarget = document.getElementById('okbtn');
var buttonClicks = Rx.DOM.fromEvent(btnTarget, 'click');
var move_to_100 = buttonClicks.map(() => {return {left: 100, top: 100}});
var change_position = Rx.Observable.merge(mousedrag, move_to_100)
change_position.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
merge
var btnTarget = document.getElementById('okbtn');
var buttonClicks = Rx.DOM.fromEvent(btnTarget, 'click');
var move_to_100 = buttonClicks.map(() => {return {left: 100, top: 100}});
var change_position = Rx.Observable.merge(mousedrag, move_to_100)
change_position.subscribe((pos) => {
dragTarget.style.top = pos.top + 'px';
dragTarget.style.left = pos.left + 'px';
});
new stream
And a lot of other methods ….
● amb
● and
● asObservable
● average
● buffer
● bufferWithCount
● bufferWithTime
● bufferWithTimeOrCount
● catch | catchError
● combineLatest
● concat
● concatAll
● concatMap
● concatMapObserver
● connect
● includes
● controlled
● count
● debounce
● debounceWithSelector
● defaultIfEmpty
● delay
● delaySubscription
● delayWithSelector
● dematerialize
● distinct
● distinctUntilChanged
● do
● doOnNext
● doOnError
● doOnCompleted
● doWhile
● elementAt
● elementAtOrDefault
● every
● expand
● extend
● filter
● find
● findIndex
● first
● firstOrDefault
● flatMap
● flatMapObserver
● flatMapLatest
● forkJoin
● groupBy
● groupByUntil
● groupJoin
● ignoreElements
● indexOf
● isEmpty
● join
● jortSort
● jortSortUntil
● last
● lastOrDefault
● merge
● mergeAll
● min
● minBy
● multicast
● observeOn
● onErrorResumeNext
● pairwise
● partition
● pausable
● pausableBuffered
● pluck
● publish
● publishLast
● publishValue
● share
● shareReplay
● shareValue
● refCount
● reduce
● repeat
● replay
● retry
● retryWhen
● sample
● scan
● select
● selectConcat
● selectConcatObserver
● selectMany
● selectManyObserver
● selectSwitch
● sequenceEqual
● single
● singleOrDefault
● singleInstance
● skip
● skipLast
● skipLastWithTime
● skipUntil
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md
Testing with time machine
Rx.TestScheduler
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
stream to test
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
Input stream messages
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
time
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
Expected result at time
var mult_stream = some_stream.debounce(100).map((n) => n * 2)
assertRxActions(
mult_stream,
[
[100, {value: 20}],
[200, {value: 40}]
],
[
[200, {value: 80}]
],
(result) => assertTrue(result)
)
callback for assert
React ?
● Rx-React
● RxReact
● cycle-react
● React RxJS Autocomplete
● React RxJS TODO MVC
● Rx TODO MVC
● React RxJS Router
● React + RxJS + Angular 2.0 di.js TODO MVC
● React + RxJS Reactive Cube
● Real-Time with React + RxJS + Meteor
● React + RxJS Flow
● Reactive Widgets
● React RxJS Infinite Scroll
Flux ?
● Rx-Flux
● ReactiveFlux
● Thundercats.js
● Flurx
● RR
RxReact
some info - http://habrahabr.ru/post/251835/
repo with demos - https://github.com/AlexMost/RxReact
RxReact (simple click count)
Simple case
demo - http://alexmost.github.io/RxReact/hello_world/public/index.html
code - https://github.com/AlexMost/RxReact/tree/master/hello_world/hello_world
dispatchActions = (view, eventStream, store) ->
incrementClickStream = eventStream
.filter(({action}) -> action is "increment_click_count")
.do(-> store.incrementClicksCount())
Rx.Observable.merge(
incrementClickStream
# some more actions here for updating view ...
).subscribe(
-> view.setProps getViewState(store)
(err) ->
console.error? err)
RxReact (simple click count)
dispatchActions = (view, eventStream, store) ->
incrementClickStream = eventStream
.filter(({action}) -> action is "increment_click_count")
.do(-> store.incrementClicksCount())
Rx.Observable.merge(
incrementClickStream
# some more actions here for updating view ...
).subscribe(
-> view.setProps getViewState(store)
(err) ->
console.error? err)
RxReact (simple click count)
stream from view for increment and storage
modification
dispatchActions = (view, eventStream, store) ->
incrementClickStream = eventStream
.filter(({action}) -> action is "increment_click_count")
.do(-> store.incrementClicksCount())
Rx.Observable.merge(
incrementClickStream
# some more actions here for updating view ...
).subscribe(
-> view.setProps getViewState(store)
(err) ->
console.error? err)
RxReact (simple click count)
merge all streams that can modify UI
dispatchActions = (view, eventStream, store) ->
incrementClickStream = eventStream
.filter(({action}) -> action is "increment_click_count")
.do(-> store.incrementClicksCount())
Rx.Observable.merge(
incrementClickStream
# some more actions here for updating view ...
).subscribe(
-> view.setProps getViewState(store)
(err) ->
console.error? err)
RxReact (simple click count)
update UI, making setProps on view
component
RxReact (simple click count)
More complex case
1. Decrement.
2. Sync with server (per 1 second).
3. Sync only if value changed.
4. Show sync success message.
5. Hide success message after 2 seconds.
demo - http://alexmost.github.io/RxReact/hello_world2/public/index.html
code - https://github.com/AlexMost/RxReact/tree/master/hello_world2/hello_world2
dispatchActions = (view, eventStream, store) ->
incrementClickStream = ...
decrementClickStream = eventStream
.filter(({action}) -> action is "decrement_click_count")
.do(-> store.decrementClickscount())
.share()
countClicksStream = Rx.Observable
.merge(incrementClickStream, decrementClickStream)
showSavedMessageStream = countClicksStream
.throttle(1000)
.distinct(-> store.getClicksCount())
.flatMap(-> saveToDb store.getClicksCount())
.do(-> store.enableSavedMessage())
hideSavedMessageStream = showSavedMessageStream.delay(2000)
.do(-> store.disableSavedMessage())
// merge ...
dispatchActions = (view, eventStream, store) ->
incrementClickStream = ...
decrementClickStream = eventStream
.filter(({action}) -> action is "decrement_click_count")
.do(-> store.decrementClickscount())
.share()
countClicksStream = Rx.Observable
.merge(incrementClickStream, decrementClickStream)
showSavedMessageStream = countClicksStream
.throttle(1000)
.distinct(-> store.getClicksCount())
.flatMap(-> saveToDb store.getClicksCount())
.do(-> store.enableSavedMessage())
hideSavedMessageStream = showSavedMessageStream.delay(2000)
.do(-> store.disableSavedMessage())
// merge ...
decrement click stream
dispatchActions = (view, eventStream, store) ->
incrementClickStream = ...
decrementClickStream = eventStream
.filter(({action}) -> action is "decrement_click_count")
.do(-> store.decrementClickscount())
.share()
countClicksStream = Rx.Observable
.merge(incrementClickStream, decrementClickStream)
showSavedMessageStream = countClicksStream
.throttle(1000)
.distinct(-> store.getClicksCount())
.flatMap(-> saveToDb store.getClicksCount())
.do(-> store.enableSavedMessage())
hideSavedMessageStream = showSavedMessageStream.delay(2000)
.do(-> store.disableSavedMessage())
// merge ...
using merge to produce all clicks stream
dispatchActions = (view, eventStream, store) ->
incrementClickStream = ...
decrementClickStream = eventStream
.filter(({action}) -> action is "decrement_click_count")
.do(-> store.decrementClickscount())
.share()
countClicksStream = Rx.Observable
.merge(incrementClickStream, decrementClickStream)
showSavedMessageStream = countClicksStream
.throttle(1000)
.distinct(-> store.getClicksCount())
.flatMap(-> saveToDb store.getClicksCount())
.do(-> store.enableSavedMessage())
hideSavedMessageStream = showSavedMessageStream.delay(2000)
.do(-> store.disableSavedMessage())
// merge ...
per 1 second
if clicks counter value changed
sync with server, wait for responce
showsuccesss message
dispatchActions = (view, eventStream, store) ->
incrementClickStream = ...
decrementClickStream = eventStream
.filter(({action}) -> action is "decrement_click_count")
.do(-> store.decrementClickscount())
.share()
countClicksStream = Rx.Observable
.merge(incrementClickStream, decrementClickStream)
showSavedMessageStream = countClicksStream
.throttle(1000)
.distinct(-> store.getClicksCount())
.flatMap(-> saveToDb store.getClicksCount())
.do(-> store.enableSavedMessage())
hideSavedMessageStream = showSavedMessageStream.delay(2000)
.do(-> store.disableSavedMessage())
// merge ...
create hide message stream
from previous
Conclusion
● Rx is a powerful tool for writing async code
● Helps to write modular and composable code
● Solves a lot of hard testing problems
● Solves problem of error handling and resource
management
Resources
http://rxmarbles.com/
http://jaredforsyth.com/rxvision/
https://github.com/jhusain/learnrx
Talk demos here
https://github.com/AlexMost/kyivjs_2015
Thanks : D

More Related Content

What's hot

如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test名辰 洪
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015NAVER / MusicPlatform
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術名辰 洪
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)Shift Conference
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)Tracy Lee
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowViliam Elischer
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stmAlexander Granin
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSRyan Anklam
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalyFabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureFabio Collini
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engineDuoyi Wu
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJSFunctional Reactive Programming with RxJS
Functional Reactive Programming with RxJSstefanmayer13
 

What's hot (20)

如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術
 
Oop assignment 02
Oop assignment 02Oop assignment 02
Oop assignment 02
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
Shift Remote FRONTEND: Reactivity in Vue.JS 3 - Marko Boskovic (Barrage)
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJS
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon Italy
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
2 презентация rx java+android
2 презентация rx java+android2 презентация rx java+android
2 презентация rx java+android
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
D3.js workshop
D3.js workshopD3.js workshop
D3.js workshop
 
Pellucid stm
Pellucid stmPellucid stm
Pellucid stm
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJSFunctional Reactive Programming with RxJS
Functional Reactive Programming with RxJS
 

Viewers also liked

Viewers also liked (6)

UX metrics
UX metricsUX metrics
UX metrics
 
Elm kyivfprog 2015
Elm kyivfprog 2015Elm kyivfprog 2015
Elm kyivfprog 2015
 
структура It компании
структура It компанииструктура It компании
структура It компании
 
Agile UX & OOUX
Agile UX & OOUXAgile UX & OOUX
Agile UX & OOUX
 
Modern javascript localization with c-3po and the good old gettext
Modern javascript localization with c-3po and the good old gettextModern javascript localization with c-3po and the good old gettext
Modern javascript localization with c-3po and the good old gettext
 
SlideShare 101
SlideShare 101SlideShare 101
SlideShare 101
 

Similar to Rxjs kyivjs 2015

WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...GeeksLab Odessa
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptjnewmanux
 
From zero to hero with the reactive extensions for JavaScript
From zero to hero with the reactive extensions for JavaScriptFrom zero to hero with the reactive extensions for JavaScript
From zero to hero with the reactive extensions for JavaScriptMaurice De Beijer [MVP]
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Codemotion
 
Funtional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTVasil Remeniuk
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Oscar Renalias
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
From zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptFrom zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptMaurice De Beijer [MVP]
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015Constantine Mars
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 

Similar to Rxjs kyivjs 2015 (20)

WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 
The Reactive Landscape
The Reactive LandscapeThe Reactive Landscape
The Reactive Landscape
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Reactive x
Reactive xReactive x
Reactive x
 
From zero to hero with the reactive extensions for JavaScript
From zero to hero with the reactive extensions for JavaScriptFrom zero to hero with the reactive extensions for JavaScript
From zero to hero with the reactive extensions for JavaScript
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
 
Funtional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWT
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
From zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptFrom zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java script
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 

Recently uploaded

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 

Recently uploaded (20)

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 

Rxjs kyivjs 2015

  • 2. About me Mostovenko Alexander Python developer at Writing mostly in python and coffeescript. Love FP stuff. Traveling, snowboarding, cycling. https://twitter.com/MostovenkoA https://github.com/AlexMost
  • 3. Why Rx.js and not another FRP lib? ● Implemented in a lot of languages (.NET, Java, Ruby, Python, Clojure, Scala, Haskell, Objective-C). ● Has a huge amount of docs and examples. ● Why not?
  • 5. Async code in javascript ● Some computation with delayed result. (data fetch, animations, DOM operations) ● Reacting to events (event handlers)
  • 6. Sync vs Async dataflow
  • 17. Asynchronous dataflow (autocomplete) time Actions keyup per 2 seconds ajax request ajax response
  • 18. Asynchronous dataflow (autocomplete) time Actions keyup per 2 seconds ajax request ajax response show suggest
  • 19. Asynchronous dataflow (autocomplete) time Actions keyup per 2 seconds ajax request ajax response show suggest
  • 20. Asynchronous dataflow (autocomplete) time Actions keyup per 2 seconds ajax request ajax response show suggest Ooooops
  • 21. Problems with async code 1. How to manage async flow in code? 2. How to handle errors? 3. How to compose?
  • 23. Callbacks ● Event notification - Yes ● Manage control flow - Nooooooooooo
  • 24. Callback hell async_func1(function(err, data){ async_func2(function(err, data){ async_func3(function(err, data){ async_func4(function(err, data){ }); }); }); });
  • 25. Callback hell yeah !!! async_func1(function(err, data){ if (!err) { async_func2(function(err, data){ if (!err) { async_func3(function(err, data){ if (!err) { async_func4(function(err, data){ }); } else { log(err); } }); } else { log(err); } }); } else { log(err); } });
  • 26. Callback hell yeah !!! async_func1(function(err, data){ if (!err) { async_func2(function(err, data){ if (!err) { async_func3(function(err, data){ if (!err) { async_func4(function(err, data){ }); } else { log(err); } }); } else { log(err); } }); } else { log(err); } }); UNREADABLE !!! UNMANAGABLE !!! UNTESTABLE !!! UNCOMPOSABLE !!! PIECE OF …. CODE
  • 27.
  • 28. Monad A monad is just a monoid in the category of endofunctors
  • 29. Callback vs Black hole some_async_func(function(err, result) { // ... looks like we are in trap another_wonderful_func(function(err, result){ // ... you are in trap }); });
  • 30. Callback vs Black Hole 1. No return value (undefined)
  • 31. Callback vs Black Hole 1. No return value (undefined) 2. One way ticket (callback hell)
  • 33. Promise var promise = new Promise((resolve, reject) => { // ... some async staff }); promise.then( (result) => {}, (error) => {} )
  • 34. Promise 1. Step forward from callbacks for control flow managing 2. Error handling
  • 35. Why we should look at Observable? 1. Promise represents only single value. 2. How to cancel? 3. Lazy execution. 4. We can work with Observable as easy as with promise.
  • 36. Promise is Observable only with a single value
  • 37. Observable The Observable object represents a push based collection.
  • 38. Observable var source = Rx.Observable.create((observer) => // some async operation observer.onNext(data) // or .. observer.onError(data) // or .. observer.onCompleted(data) ); source.subscribe( (data) => {} (err) => {} )
  • 39. Observlable vs promise example var source = Rx.Observable.create((observer) => { setTimeout(() => { console.log("observable timeout hit"); observer.onNext(25); }, 500); console.log('observable started')}); source.subscribe(x => console.log(`observable value ${x}`)); Observable > observable started > observable timeout hit > observable value 25
  • 40. Observlable vs promise example var promise = new Promise((resolve) => { setTimeout(() => { console.log("promise timeout hit"); resolve(25); }, 500); console.log("promise started");}); promise.then(x => console.log(`promise value ${x}`)); Promise > promise started > promise timeout hit > promise value 25
  • 41. Lazy execution var source = Rx.Observable.create((observer) => { setTimeout(() => { console.log("observable timeout hit"); observer.onNext(25); }, 500); console.log('observable started')}); // source.subscribe(x => console.log(`observable value ${x}`)); >
  • 42. Observable can be canceled var source = Rx.Observable.create((observer) => { var id = setTimeout(() => { console.log("observable timeout hit"); observer.onNext(25); }, 500); console.log('observable started'); return () => { console.log("dispose called") clearTimeout(id);} }); var disposable = source.subscribe( x => console.log(`observable value ${x}`)); setTimeout(() => disposable.dispose(), 100) > observable started > dispose called
  • 43. Asynchronous programming landscape multiple values single value sync async a = f(x) a = f(x).then(...) collection = [1, 2, 3] a = collection .filter((v) => v > 2) Promise Array Sync value ?
  • 44. Asynchronous programming landscape multiple values single value sync async a = f(x) a = f(x).then(...) collection = [1, 2, 3] a = collection .filter((v) => v > 2) move = Rx.Observable.fromEvent(document, 'mousemove') my_moves = move .filter((ev) => ev.clientX > 100) my_moves.subscribe(...) Promise Array value Observable
  • 45. How to create Observable ● Observable.create ● Observable.fromEvent ● Observable.fromNodeCallback ● Observable.fromArray ● Observable.fromPromise
  • 46. Drag & Drop example What if i told you …. That mouse move event is an array and you can map, filter over it?
  • 47. var dragTarget = document.getElementById('dragTarget'); // Get the three major events collections var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup'); var mousemove = Rx.DOM.fromEvent(document, 'mousemove'); var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown'); var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); var subscription = mousedrag.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; });
  • 48. var dragTarget = document.getElementById('dragTarget'); // Get the three major events collections var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup'); var mousemove = Rx.DOM.fromEvent(document, 'mousemove'); var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown'); var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); var subscription = mousedrag.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; }); Create observable collections from DOM events
  • 49. var dragTarget = document.getElementById('dragTarget'); // Get the three major events collections var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup'); var mousemove = Rx.DOM.fromEvent(document, 'mousemove'); var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown'); var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); var subscription = mousedrag.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; }); Using power of Rx, combine existing event streams to produce mouse drag event collection
  • 50. var dragTarget = document.getElementById('dragTarget'); // Get the three major events collections var mouseup = Rx.DOM.fromEvent(dragTarget, 'mouseup'); var mousemove = Rx.DOM.fromEvent(document, 'mousemove'); var mousedown = Rx.DOM.fromEvent(dragTarget, 'mousedown'); var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); var subscription = mousedrag.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; }); Subscribe on mouse drag events, updating top and left attributes
  • 51. Observable are first class events Can be: - passed as a parameter - returned from a function - assigned to a variable
  • 52.
  • 53. Some common basic operations map filter reduce zip merge flatMap ... https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md
  • 56. var mousedrag_in_area = mousedrag.filter(({top, left}) => { return top <= 200 && left <= 200 }); var subscription = mousedrag_in_area.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; }); let’s filter drag area
  • 58. let’s create slow mouse drag var slow_mousedrag = mousedrag.delay(700) var subscription = slow_mousedrag.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; });
  • 60. let’s record our drag path var drag_path = mousedrag .takeUntil(mouseup) .reduce(((a, b) => a + `${b.top} ${b.left};`), "") drag_path.subscribe((path) => pathTarget.innerHTML = path)
  • 62. flatMap var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) });
  • 63. flatMap var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); Outer stream
  • 64. flatMap var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) }); value as a stream
  • 66. merge var btnTarget = document.getElementById('okbtn'); var buttonClicks = Rx.DOM.fromEvent(btnTarget, 'click'); var move_to_100 = buttonClicks.map(() => {return {left: 100, top: 100}}); var change_position = Rx.Observable.merge(mousedrag, move_to_100) change_position.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; });
  • 67. merge var btnTarget = document.getElementById('okbtn'); var buttonClicks = Rx.DOM.fromEvent(btnTarget, 'click'); var move_to_100 = buttonClicks.map(() => {return {left: 100, top: 100}}); var change_position = Rx.Observable.merge(mousedrag, move_to_100) change_position.subscribe((pos) => { dragTarget.style.top = pos.top + 'px'; dragTarget.style.left = pos.left + 'px'; }); new stream
  • 68. And a lot of other methods …. ● amb ● and ● asObservable ● average ● buffer ● bufferWithCount ● bufferWithTime ● bufferWithTimeOrCount ● catch | catchError ● combineLatest ● concat ● concatAll ● concatMap ● concatMapObserver ● connect ● includes ● controlled ● count ● debounce ● debounceWithSelector ● defaultIfEmpty ● delay ● delaySubscription ● delayWithSelector ● dematerialize ● distinct ● distinctUntilChanged ● do ● doOnNext ● doOnError ● doOnCompleted ● doWhile ● elementAt ● elementAtOrDefault ● every ● expand ● extend ● filter ● find ● findIndex ● first ● firstOrDefault ● flatMap ● flatMapObserver ● flatMapLatest ● forkJoin ● groupBy ● groupByUntil ● groupJoin ● ignoreElements ● indexOf ● isEmpty ● join ● jortSort ● jortSortUntil ● last ● lastOrDefault ● merge ● mergeAll ● min ● minBy ● multicast ● observeOn ● onErrorResumeNext ● pairwise ● partition ● pausable ● pausableBuffered ● pluck ● publish ● publishLast ● publishValue ● share ● shareReplay ● shareValue ● refCount ● reduce ● repeat ● replay ● retry ● retryWhen ● sample ● scan ● select ● selectConcat ● selectConcatObserver ● selectMany ● selectManyObserver ● selectSwitch ● sequenceEqual ● single ● singleOrDefault ● singleInstance ● skip ● skipLast ● skipLastWithTime ● skipUntil https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md
  • 69. Testing with time machine Rx.TestScheduler
  • 70. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) )
  • 71. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) ) stream to test
  • 72. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) ) Input stream messages
  • 73. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) ) time
  • 74. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) ) Expected result at time
  • 75. var mult_stream = some_stream.debounce(100).map((n) => n * 2) assertRxActions( mult_stream, [ [100, {value: 20}], [200, {value: 40}] ], [ [200, {value: 80}] ], (result) => assertTrue(result) ) callback for assert
  • 76. React ? ● Rx-React ● RxReact ● cycle-react ● React RxJS Autocomplete ● React RxJS TODO MVC ● Rx TODO MVC ● React RxJS Router ● React + RxJS + Angular 2.0 di.js TODO MVC ● React + RxJS Reactive Cube ● Real-Time with React + RxJS + Meteor ● React + RxJS Flow ● Reactive Widgets ● React RxJS Infinite Scroll
  • 77. Flux ? ● Rx-Flux ● ReactiveFlux ● Thundercats.js ● Flurx ● RR
  • 78. RxReact some info - http://habrahabr.ru/post/251835/ repo with demos - https://github.com/AlexMost/RxReact
  • 79. RxReact (simple click count) Simple case demo - http://alexmost.github.io/RxReact/hello_world/public/index.html code - https://github.com/AlexMost/RxReact/tree/master/hello_world/hello_world
  • 80. dispatchActions = (view, eventStream, store) -> incrementClickStream = eventStream .filter(({action}) -> action is "increment_click_count") .do(-> store.incrementClicksCount()) Rx.Observable.merge( incrementClickStream # some more actions here for updating view ... ).subscribe( -> view.setProps getViewState(store) (err) -> console.error? err) RxReact (simple click count)
  • 81. dispatchActions = (view, eventStream, store) -> incrementClickStream = eventStream .filter(({action}) -> action is "increment_click_count") .do(-> store.incrementClicksCount()) Rx.Observable.merge( incrementClickStream # some more actions here for updating view ... ).subscribe( -> view.setProps getViewState(store) (err) -> console.error? err) RxReact (simple click count) stream from view for increment and storage modification
  • 82. dispatchActions = (view, eventStream, store) -> incrementClickStream = eventStream .filter(({action}) -> action is "increment_click_count") .do(-> store.incrementClicksCount()) Rx.Observable.merge( incrementClickStream # some more actions here for updating view ... ).subscribe( -> view.setProps getViewState(store) (err) -> console.error? err) RxReact (simple click count) merge all streams that can modify UI
  • 83. dispatchActions = (view, eventStream, store) -> incrementClickStream = eventStream .filter(({action}) -> action is "increment_click_count") .do(-> store.incrementClicksCount()) Rx.Observable.merge( incrementClickStream # some more actions here for updating view ... ).subscribe( -> view.setProps getViewState(store) (err) -> console.error? err) RxReact (simple click count) update UI, making setProps on view component
  • 84. RxReact (simple click count) More complex case 1. Decrement. 2. Sync with server (per 1 second). 3. Sync only if value changed. 4. Show sync success message. 5. Hide success message after 2 seconds. demo - http://alexmost.github.io/RxReact/hello_world2/public/index.html code - https://github.com/AlexMost/RxReact/tree/master/hello_world2/hello_world2
  • 85. dispatchActions = (view, eventStream, store) -> incrementClickStream = ... decrementClickStream = eventStream .filter(({action}) -> action is "decrement_click_count") .do(-> store.decrementClickscount()) .share() countClicksStream = Rx.Observable .merge(incrementClickStream, decrementClickStream) showSavedMessageStream = countClicksStream .throttle(1000) .distinct(-> store.getClicksCount()) .flatMap(-> saveToDb store.getClicksCount()) .do(-> store.enableSavedMessage()) hideSavedMessageStream = showSavedMessageStream.delay(2000) .do(-> store.disableSavedMessage()) // merge ...
  • 86. dispatchActions = (view, eventStream, store) -> incrementClickStream = ... decrementClickStream = eventStream .filter(({action}) -> action is "decrement_click_count") .do(-> store.decrementClickscount()) .share() countClicksStream = Rx.Observable .merge(incrementClickStream, decrementClickStream) showSavedMessageStream = countClicksStream .throttle(1000) .distinct(-> store.getClicksCount()) .flatMap(-> saveToDb store.getClicksCount()) .do(-> store.enableSavedMessage()) hideSavedMessageStream = showSavedMessageStream.delay(2000) .do(-> store.disableSavedMessage()) // merge ... decrement click stream
  • 87. dispatchActions = (view, eventStream, store) -> incrementClickStream = ... decrementClickStream = eventStream .filter(({action}) -> action is "decrement_click_count") .do(-> store.decrementClickscount()) .share() countClicksStream = Rx.Observable .merge(incrementClickStream, decrementClickStream) showSavedMessageStream = countClicksStream .throttle(1000) .distinct(-> store.getClicksCount()) .flatMap(-> saveToDb store.getClicksCount()) .do(-> store.enableSavedMessage()) hideSavedMessageStream = showSavedMessageStream.delay(2000) .do(-> store.disableSavedMessage()) // merge ... using merge to produce all clicks stream
  • 88. dispatchActions = (view, eventStream, store) -> incrementClickStream = ... decrementClickStream = eventStream .filter(({action}) -> action is "decrement_click_count") .do(-> store.decrementClickscount()) .share() countClicksStream = Rx.Observable .merge(incrementClickStream, decrementClickStream) showSavedMessageStream = countClicksStream .throttle(1000) .distinct(-> store.getClicksCount()) .flatMap(-> saveToDb store.getClicksCount()) .do(-> store.enableSavedMessage()) hideSavedMessageStream = showSavedMessageStream.delay(2000) .do(-> store.disableSavedMessage()) // merge ... per 1 second if clicks counter value changed sync with server, wait for responce showsuccesss message
  • 89. dispatchActions = (view, eventStream, store) -> incrementClickStream = ... decrementClickStream = eventStream .filter(({action}) -> action is "decrement_click_count") .do(-> store.decrementClickscount()) .share() countClicksStream = Rx.Observable .merge(incrementClickStream, decrementClickStream) showSavedMessageStream = countClicksStream .throttle(1000) .distinct(-> store.getClicksCount()) .flatMap(-> saveToDb store.getClicksCount()) .do(-> store.enableSavedMessage()) hideSavedMessageStream = showSavedMessageStream.delay(2000) .do(-> store.disableSavedMessage()) // merge ... create hide message stream from previous
  • 90. Conclusion ● Rx is a powerful tool for writing async code ● Helps to write modular and composable code ● Solves a lot of hard testing problems ● Solves problem of error handling and resource management