SlideShare a Scribd company logo
1 of 98
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 (streams).
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}`));
>
Promise can’t do that
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
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
Observable stream from :
● 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?
demo - http://alexmost.github.io/talks/rx.js/demo/drag_and_drop.html
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 objects
Can be:
- passed as a parameter
- returned from a function
- assigned to a variable
Live example - Morse parser
Morse logic
1. Parse signals (.... --- … ---)
2. Parse spaces (letters - 3 span, word - 7 span)
3. Decode in Letters
4. Collect in words
Demo
http://alexmost.github.io/morse/
source - https://github.com/AlexMost/morse
Challenges
1. Dot or line?
2. Different length of letter codes.
3. Track pause between letters (3 spans).
4. Track pause between words (7 spans).
DOM events (keyUp, keyDown, Click, e.t.c)
Signal start, signal end
dots, lines, spaces
letter codes (array of dot’s and lines)
words, letters, sentence
Composable streams
DOM events (keyUp, keyDown, Click, e.t.c)
Signal start, signal end
dots, lines, spaces
letter codes (array of dot’s and lines)
words, letters, sentence
Can use each separately
Space key down/up as collection
var spaceKeyDowns = Rx.Observable.fromEvent(document, 'keydown').filter((ev) => ev.keyCode == 32)
var spaceKeyUps = Rx.Observable.fromEvent(document, 'keyup').filter((ev) => ev.keyCode == 32)
Code for dot’s and lines
var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp()
var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp()
var signalTimeSpans = signalStarts.flatMap((startArgs) => {
return signalEnds
.map((endArgs) => endArgs.timestamp - startArgs.timestamp)
.first()
})
var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".")
var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-")
var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream)
Code for dot’s and lines
var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp()
var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp()
var signalTimeSpans = signalStarts.flatMap((startArgs) => {
return signalEnds
.map((endArgs) => endArgs.timestamp - startArgs.timestamp)
.first()
})
var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".")
var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-")
var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream)
Abstraction on top of key down,
key up, mouse down, mouse up,
e.t.c with timestamp
Code for dot’s and lines
var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp()
var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp()
var signalTimeSpans = signalStarts.flatMap((startArgs) => {
return signalEnds
.map((endArgs) => endArgs.timestamp - startArgs.timestamp)
.first()
})
var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".")
var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-")
var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream)
Signal duration count
Code for dot’s and lines
var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp()
var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp()
var signalTimeSpans = signalStarts.flatMap((startArgs) => {
return signalEnds
.map((endArgs) => endArgs.timestamp - startArgs.timestamp)
.first()
})
var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".")
var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-")
var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream)
dot’s stream
lines stream
Code for dot’s and lines
var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp()
var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp()
var signalTimeSpans = signalStarts.flatMap((startArgs) => {
return signalEnds
.map((endArgs) => endArgs.timestamp - startArgs.timestamp)
.first()
})
var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".")
var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-")
var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream) dot’s and lines !!!
Push based collections in result
var lettersStream = letterCodes.map((codes) => morse.decode(codes.join("")))
var wordsStream = lettersStream.buffer(wordsWhitespaces).map((w) => w.join(""))
Use Observable as collection
var setCatImgStream = wordsStream.filter((word) => word == "CAT").map(setCatImg)
Cat demo
http://alexmost.github.io/morse/
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
demo - http://alexmost.github.io/talks/rx.js/demo/filter.html
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';
});
demo - http://alexmost.github.io/talks/rx.js/demo/delay.html
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)
demo - http://alexmost.github.io/talks/rx.js/demo/reduce.html
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 demo
demo - http://alexmost.github.io/talks/rx.js/demo/merge.html
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
Conclusion
● Use Rx
Resources
http://rxmarbles.com/
http://jaredforsyth.com/rxvision/
https://github.com/jhusain/learnrx
Talk demos here
https://github.com/AlexMost/talks/tree/master/rx.js
Thanks : D

More Related Content

What's hot

You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017名辰 洪
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
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
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015Ben Lesh
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript名辰 洪
 
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
 
如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test名辰 洪
 
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
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術名辰 洪
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
Ns2: Introduction - Part I
Ns2: Introduction - Part INs2: Introduction - Part I
Ns2: Introduction - Part IAjit Nayak
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptCaridy Patino
 
Ns2: OTCL - PArt II
Ns2: OTCL - PArt IINs2: OTCL - PArt II
Ns2: OTCL - PArt IIAjit Nayak
 

What's hot (20)

You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
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
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 
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
 
如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test如何「畫圖」寫測試 - RxJS Marble Test
如何「畫圖」寫測試 - RxJS Marble Test
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術
 
Oop assignment 02
Oop assignment 02Oop assignment 02
Oop assignment 02
 
The State of JavaScript
The State of JavaScriptThe State of JavaScript
The State of JavaScript
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Ns2: Introduction - Part I
Ns2: Introduction - Part INs2: Introduction - Part I
Ns2: Introduction - Part I
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
 
Ns2: OTCL - PArt II
Ns2: OTCL - PArt IINs2: OTCL - PArt II
Ns2: OTCL - PArt II
 
Map kit light
Map kit lightMap kit light
Map kit light
 

Viewers also liked

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 gettextAlexander Mostovenko
 
The Future starts with a Promise
The Future starts with a PromiseThe Future starts with a Promise
The Future starts with a PromiseAlexandru Nedelcu
 
React server side rendering performance
React server side rendering performanceReact server side rendering performance
React server side rendering performanceNick Dreckshage
 
Com_21
Com_21Com_21
Com_21Rujruj
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Reactive design: languages, and paradigms
Reactive design: languages, and paradigmsReactive design: languages, and paradigms
Reactive design: languages, and paradigmsDean Wampler
 
RxJS - The Reactive Extensions for JavaScript
RxJS - The Reactive Extensions for JavaScriptRxJS - The Reactive Extensions for JavaScript
RxJS - The Reactive Extensions for JavaScriptViliam Elischer
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaKasun Indrasiri
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015Ben Lesh
 
Performance and Scalability Art of Isomorphic React Applications
Performance and Scalability Art of Isomorphic React ApplicationsPerformance and Scalability Art of Isomorphic React Applications
Performance and Scalability Art of Isomorphic React ApplicationsDenis Izmaylov
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with DataSeth Familian
 

Viewers also liked (17)

Elm kyivfprog 2015
Elm kyivfprog 2015Elm kyivfprog 2015
Elm kyivfprog 2015
 
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
 
UX metrics
UX metricsUX metrics
UX metrics
 
The Future starts with a Promise
The Future starts with a PromiseThe Future starts with a Promise
The Future starts with a Promise
 
структура It компании
структура It компанииструктура It компании
структура It компании
 
React server side rendering performance
React server side rendering performanceReact server side rendering performance
React server side rendering performance
 
Agile UX & OOUX
Agile UX & OOUXAgile UX & OOUX
Agile UX & OOUX
 
Com_21
Com_21Com_21
Com_21
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Reactive design: languages, and paradigms
Reactive design: languages, and paradigmsReactive design: languages, and paradigms
Reactive design: languages, and paradigms
 
RxJS - The Reactive Extensions for JavaScript
RxJS - The Reactive Extensions for JavaScriptRxJS - The Reactive Extensions for JavaScript
RxJS - The Reactive Extensions for JavaScript
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-Java
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
 
Performance and Scalability Art of Isomorphic React Applications
Performance and Scalability Art of Isomorphic React ApplicationsPerformance and Scalability Art of Isomorphic React Applications
Performance and Scalability Art of Isomorphic React Applications
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
SlideShare 101
SlideShare 101SlideShare 101
SlideShare 101
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with Data
 

Similar to rx.js make async programming simpler

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]
 
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
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 
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]
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
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
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftFlorent Pillet
 
Reactive programming and RxJS
Reactive programming and RxJSReactive programming and RxJS
Reactive programming and RxJSRavi Mone
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for AndroidTomáš Kypta
 
Cycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI frameworkCycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI frameworkNikos Kalogridis
 
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)GreeceJS
 

Similar to rx.js make async programming simpler (20)

Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
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
 
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
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 
Reactive x
Reactive xReactive x
Reactive x
 
The Reactive Landscape
The Reactive LandscapeThe Reactive Landscape
The Reactive Landscape
 
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
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
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
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Reactive programming and RxJS
Reactive programming and RxJSReactive programming and RxJS
Reactive programming and RxJS
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Cycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI frameworkCycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI framework
 
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
 

Recently uploaded

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 

Recently uploaded (20)

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 

rx.js make async programming simpler

  • 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 (streams).
  • 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. Promise can’t do that 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
  • 43. 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
  • 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) Promise Array Sync value ?
  • 45. 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
  • 46. Observable stream from : ● Observable.create ● Observable.fromEvent ● Observable.fromNodeCallback ● Observable.fromArray ● Observable.fromPromise
  • 47. Drag & Drop example What if i told you …. That mouse move event is an array and you can map, filter over it? demo - http://alexmost.github.io/talks/rx.js/demo/drag_and_drop.html
  • 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'; });
  • 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'; }); Create observable collections from DOM events
  • 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'; }); Using power of Rx, combine existing event streams to produce mouse drag event collection
  • 51. 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
  • 52. Observable are first class objects Can be: - passed as a parameter - returned from a function - assigned to a variable
  • 53. Live example - Morse parser
  • 54. Morse logic 1. Parse signals (.... --- … ---) 2. Parse spaces (letters - 3 span, word - 7 span) 3. Decode in Letters 4. Collect in words
  • 56. Challenges 1. Dot or line? 2. Different length of letter codes. 3. Track pause between letters (3 spans). 4. Track pause between words (7 spans).
  • 57. DOM events (keyUp, keyDown, Click, e.t.c) Signal start, signal end dots, lines, spaces letter codes (array of dot’s and lines) words, letters, sentence Composable streams
  • 58. DOM events (keyUp, keyDown, Click, e.t.c) Signal start, signal end dots, lines, spaces letter codes (array of dot’s and lines) words, letters, sentence Can use each separately
  • 59. Space key down/up as collection var spaceKeyDowns = Rx.Observable.fromEvent(document, 'keydown').filter((ev) => ev.keyCode == 32) var spaceKeyUps = Rx.Observable.fromEvent(document, 'keyup').filter((ev) => ev.keyCode == 32)
  • 60. Code for dot’s and lines var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp() var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp() var signalTimeSpans = signalStarts.flatMap((startArgs) => { return signalEnds .map((endArgs) => endArgs.timestamp - startArgs.timestamp) .first() }) var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".") var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-") var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream)
  • 61. Code for dot’s and lines var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp() var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp() var signalTimeSpans = signalStarts.flatMap((startArgs) => { return signalEnds .map((endArgs) => endArgs.timestamp - startArgs.timestamp) .first() }) var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".") var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-") var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream) Abstraction on top of key down, key up, mouse down, mouse up, e.t.c with timestamp
  • 62. Code for dot’s and lines var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp() var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp() var signalTimeSpans = signalStarts.flatMap((startArgs) => { return signalEnds .map((endArgs) => endArgs.timestamp - startArgs.timestamp) .first() }) var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".") var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-") var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream) Signal duration count
  • 63. Code for dot’s and lines var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp() var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp() var signalTimeSpans = signalStarts.flatMap((startArgs) => { return signalEnds .map((endArgs) => endArgs.timestamp - startArgs.timestamp) .first() }) var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".") var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-") var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream) dot’s stream lines stream
  • 64. Code for dot’s and lines var signalStarts = eventStream.filter(({action}) => action === "signal_start").timestamp() var signalEnds = eventStream.filter(({action}) => action === "signal_end").timestamp() var signalTimeSpans = signalStarts.flatMap((startArgs) => { return signalEnds .map((endArgs) => endArgs.timestamp - startArgs.timestamp) .first() }) var dotsStream = signalTimeSpans.filter((v) => v <= SPAN).map(() => ".") var lineStream = signalTimeSpans.filter((v) => v > SPAN).map(() => "-") var dotsAndLines = Rx.Observable.merge(dotsStream, lineStream) dot’s and lines !!!
  • 65. Push based collections in result var lettersStream = letterCodes.map((codes) => morse.decode(codes.join(""))) var wordsStream = lettersStream.buffer(wordsWhitespaces).map((w) => w.join(""))
  • 66. Use Observable as collection var setCatImgStream = wordsStream.filter((word) => word == "CAT").map(setCatImg)
  • 68.
  • 69. Some common basic operations map filter reduce zip merge flatMap ... https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md
  • 72. 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 demo - http://alexmost.github.io/talks/rx.js/demo/filter.html
  • 74. 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'; }); demo - http://alexmost.github.io/talks/rx.js/demo/delay.html
  • 76. 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) demo - http://alexmost.github.io/talks/rx.js/demo/reduce.html
  • 78. flatMap var mousedrag = mousedown.flatMap(({offsetX, offsetY}) => { return mousemove .map(({clientX: x, clientY: y}) => { return {left: x - offsetX, top: y - offsetY}}) .takeUntil(mouseup) });
  • 79. 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
  • 80. 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
  • 82. merge demo demo - http://alexmost.github.io/talks/rx.js/demo/merge.html
  • 83. 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'; });
  • 84. 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
  • 85. 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
  • 86. Testing with time machine Rx.TestScheduler
  • 87. 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) )
  • 88. 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
  • 89. 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
  • 90. 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
  • 91. 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
  • 92. 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
  • 93. 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
  • 94. Flux ? ● Rx-Flux ● ReactiveFlux ● Thundercats.js ● Flurx ● RR