SlideShare a Scribd company logo
RxJs - demystified
Christoffer Noring
@chris_noring
Lodash for async
Who am I
@chris_noring
What is reactive programming?
Is a programming paradigm
Focuses on propagating changes
without us having to explicitly specify how the propagation happens
State what our code should to
without having to code every line
Functional programming
Avoid mutable state
Avoid side-effects
Functional composition over object composition
= programs with predictable outcome
Functional over imperative
var list = [ 1,2,3,4,5 ];
var newList = list.map( function(value) {
return value + 1;
})
Produces a new list
list NOT mutated/changed
but projected
Functional
Imperative
var list = [ 1,2,3,4,5 ];
list.forEach( function(value) {
value += 1;
})
X number invocation changes state
Reactive programming
Async data streams
Turn
click events
user inputs
data from server
callbacks into a stream
One paradigm/ api to rule them all
Observable pattern
Iterative pattern
Observer
Observable, observable sequence
= Rx pattern
Emits its values in order, like an iterator,
BUT pushes values as they become available
Has access to a producer in an observable pattern
Push-based behaviour,
don’t call us, we’ll call you
Consumer of an observable
Like listener in observable pattern
Doesn’t start streaming unless it has at least
one Observer subscribed to it
At the heart of everything is the
Observable
Promise vs Array vs
Observable
list
.map( x = > x.prop )
.filter( x => x > 2 )
.take( 2 )
list
.map( x = > x.prop )
.filter( x => x > 2 )
.take( 2 )
.subscribe(
x => console.log(x),
)
Array Observable
Promise
service.get()
.then( x => console.log(x) )
)
Array like,
handles async
but can also
- Cancelled
- Retried
Observable vs Observable pattern
function Producer(){
this.listeners = [];
}
Producer.prototype.add = function(listener){
this.listeners.push( listener );
}
Producer.prototype.notify = function(message){
this.listeners.forEach( function(listener){
listener.update( message );
})
}
var stream = new Rx.Observable(function(observer) {
observer.onNext('message');
})
stream.subscribe( function(val){
console.log( val );
})
Observable is usually NOT the producer,
it has access to one though
var stream = new Rx.Observable(function(observer){
var producer = new Producer();
producer.nextValue( function(val){
observer.onNext( val );
})
})
function Producer(){
}
Producer.prototype.nextValue = function(cb){
setTimeout(function(){
cb( 1 );
},2000);
}
Producer created internally =
“cold observable”
Also responsible for emitting value
to observer
Observable
Rx.Observable.create(
onValueCallback,
onErrorCallback,
onCompletedCallback
)
Optional
Marble diagrams
Operation
Stream
Other stream
Resulting stream
1 2 3
4 5
1 2 3 4 5
Most operators are covered at rxmarbles.com
Observable
with error
var stream = Rx.Observable.create(function(observer){
observer.onNext(1);
observer.onNext(2);
observer.onNext(3);
observer.onError( ‘there is an error’ )
})
stream.subscribe(
function(data){ console.log( data ); },
function(error) { console.error( error ); }
)
Observable
with completed
var stream = Rx.Observable.create(function(observer){
observer.onNext( 1 );
observer.onNext( 2 );
observer.onNext( 3 );
observer.onCompleted();
})
stream.subscribe(
function(data){ console.log( data ); },
function(error){ console.error( error ); },
function(){ console.info( “completed” ); }
)
Observable
cancelling
var homemadeStream = Rx.Observable.create((observer) => {
var i=0;
var handle = setInterval(function() {
observer.onNext( i++ );
}, 500);
return function(){
console.log('Disposing timeout');
clearTimeout( handle );
}
});
var subscription2 = homemadeStream.subscribe((val) => {
console.log('Homemade val',val);
});
setTimeout(function() {
console.log('Cancelling homemadeStream');
subscription2.dispose();
}, 1500);
Define whats to happen on dispose
Calling dispose
Produce values till someone calls dispose
Observable
create your own
var stream = Rx.Observable.create(function(observer){
observer.onNext(1);
observer.onNext(2);
observer.onNext(3);
})
stream.subscribe( function(data){ console.log( data ); } )
Stream 1 2 3
onNext() onNext()
Observable
wrap ajax
var stream = Rx.Observable.create(function(observer){
var request = new XMLHttpRequest();
request.open( ‘GET’, ‘url’ );
request.onload = function(){
if(request.status === 200) {
observer.onNext( request.response );
observer.onCompleted();
} else {
observer.onError( new Error( request.statusText ) )
}
}
request.onerror = function(){ observer.onError( new Error(‘unknown error’) ); }
request.send();
})
stream.subscribe( function(result) { console.log( result ); } )
Producer
Operators
120+ operators
Combination Conditional
Creational
Error handling
Multicasting
Filtering
Transformation
Utility
Categories
Operators
multicasting
Cold observable = producer is not shared
var cold = new Observable((observer) => {
var producer = new Producer();
// have observer listen to producer here
});
var producer = new Producer();
var hot = new Observable((observer) => {
// have observer listen to producer here
});
A producer is the source of values for your observable.
Operators
multicasting
Going from hot to cold
Operators
multicasting
var stream = Rx.Observable.interval(1000);
stream.subscribe(function(val){
console.log('Subscriber 1', val);
});
stream.subscribe(function(val){
console.log('Subscriber 2', val);
});
By definition cold,
as both subscriber start from 0,1 ..
NOT shared
Subscriber 1 ,0
Subscriber 2 ,0
Starts on same number
Operators
multicasting
How to share?
stream.subscribe(function(val){
console.log('Subscriber 1', val);
});
setTimeout(function() {
stream.connect();
}, 2000);
setTimeout(function() {
stream.subscribe(function(val){
console.log('Started after 4 sec, Subscriber 2', val);
});
}, 4000);
var stream = Rx.Observable.interval(1000)
.publish();
Sits and wait til
Observable,
creating
Rx.Observable.fromArray([ 1,2,3,4 ])
Rx.Observable.fromEvent(element, ‘event’);
Rx.Observable.fromArray(eventEmitter, ‘data’, function(){})
Rx.Observable.fromNodeCallback(fs.createFile)
Rx.Observable.fromCallback(obj.callback)
Rx.Observable.fromPromise(promise)
Rx.Observable.fromIterable(function *() { yield 20 })
Rx.Observable.range(1,3)
Rx.Observable.interval(miliseconds)
Observable
common operators
var stream = Rx.Observable.of(1,2,3,4,5);
stream.map((val) => {
return val + 1;
})
.filter((val) => {
return val % 3 === 0;
})
Investigates every value
Observable
reducer
var stream2 = Rx.Observable.of(1,2,3,4,5,6);
var subscription2 = stream2.reduce((acc, curr) => {
return acc + curr;
});
subscription2.subscribe((val) => {
console.log('Sum', val);
})
Operators
utility
Operators
utility
var stream = Rx.Observable.of(1,2,3,4,5);
var subscription = stream
.do(function(val){
console.log('Current val', val);
})
.filter(function(val){
return val % 2 === 0;
});
subscription.subscribe(function(val){
console.log('Val',val);
})
Echos every value
without changing it,
used for logging
Do
Operators
utility
toPromise Used to create a promise
from an observable
stream
.filter(function(val){
return val % 2 === 0;
})
.toPromise()
.then( function(val){
console.log('Promise', val);
}) 4
var stream = Rx.Observable.of(1,2,3,4,5);
Only latest value that fulfils filter is returned
Operators
utility
let
stream
.let( observable =>
observable
.filter(function(x){
return x % 2 > 0;
}))
.take(2)
.subscribe(function(val){
console.log('let', val);
})
Let’s us operate on the
observable.
We don’t need to return
what we do
like with a normal operator
stream
.filter(function(val){
return val % 2 === 0;
})
var stream = Rx.Observable.of(1,2,3,4,5);
Operators
utilityDelay,
the whole sequence
stream
.delay(1000)
.subscribe( (val) => {
var newTime = new Date().getTime();
console.log('Delayed', val + " " + (newTime - time));
})
Rx.Observable.merge(
Rx.Observable.of('Marco').delay(1000),
Rx.Observable.of('Polo').delay(2000)
).subscribe((val) => {
var newTime = new Date().getTime();
console.log('Merged Delay', val + " " + (newTime - time));
})
….. 1 second
1
2
3
….. 1 second
Marco
….. 2 second
Polo
Operators
combination
Operators
combination
concat
merge
var concat = Rx.Observable.concat(
stream,
stream2
);
var stream = Rx.Observable.fromArray([1,2,3,4]);
var stream2 = Rx.Observable.fromArray([5,6,7,8]);
1, 2, 3, 4, 5, 6, 7 ,8
var merge = Rx.Observable.merge(
stream,
stream2
);
1, 5, 2, 6, 3, 7, 4 ,8
first stream emits all values
then remaining value
streams take turn
There is difference so choose wisely
Operators
combination
var stream = Rx.Observable.fromArray([1,2,3,4]);
var stream2 = Rx.Observable.fromArray([5,6,7,8]);
var combineLatest = Rx.Observable.combineLatest(
stream,
stream2
);
combineLatest.subscribe( function(val) {
console.log( 'combine ', val )
})
combineLatest
[1,5], [2,6], [3,7], [4,8]
Operators
conditional
Operators
conditional
var stream =
Rx.Observable
.fromArray([1,2,3,4])
.every( function(val){
return val % 2 === 0;
});
false
var evenStream =
Rx.Observable
.fromArray([2,4,8])
.every( function(val){
return val % 2 === 0
});
true
Condition needs to be fulfilled on all values
Operators
filtering
Operators
filtering
var debounceTime = Rx.Observable
.fromEvent(button,'click')
.debounce(2000);
debounceTime.subscribe( function(){
console.log('mouse pressed');
})
waits x ms and
returns latest emitted
var debouncedStream = Rx.Observable
.fromArray([1,2])
.debounce(25);
debouncedStream.subscribe( function(val){
console.log('debounce stream', val );
});
returns 2
ex1
ex2
Ignores all generated
mouse click events
for 2 seconds
Operators
filtering
var mousePressedTimer = Rx.Observable.interval(1000);
mousePressedTimer
.takeUntil( mouseUp )
.subscribe( function(val){
console.log('mouse up has NOT happened yet',val);
}, function(err){},
function(){
console.log('condition fulfilled');
})
var mouseUp = Rx.Observable.fromEvent(button,'mouseup');
Break condition
Generate numbers
var throttle = Rx.Observable
.interval( 1000 )
.throttle( 1000 );
throttle.subscribe( function(val){
console.log('Throttle', val );
});
Operators
filtering
Delay every value
by x milliseconds
Throttle
1 2 3 4
1 2
Operators
transformation
Operators
transformation
var numbers = Rx.Observable.interval(1000);
var bufferBy = Rx.Observable.fromEvent(document,'click');
var buffered = numbers.buffer( bufferBy );
buffered.subscribe(function(values){
console.log('Buffered',values);
});
[1,2]
[3,4,5,6,7]
etc…
Numbers are generated to a buffer
until condition is met,
then the buffer content is emitted
Buffer
Operators
transformation
var bufferTime = numbers.bufferTime(2000);
bufferTime.subscribe(function(values){
console.log("Buffer time",values);
})
var numbers = Rx.Observable.interval(1000);
Waits x miliseconds and then emits buffer
BufferTime
var expand = Rx.Observable
.of(2)
.expand(function(val){
return Rx.Observable.of(1 + val);
})
.take(3);
expand.subscribe(function(val){
console.log('Expand',val);
})
Operators
transformationExpand
Recursively call provided callback
x times
Operators
transformation
Scan
var scanning = Rx.Observable
.of({ prop : 'a'}, { prop2 : 'b'})
.scan((acc, curr) => Object.assign({}, acc, curr), {});
scanning.subscribe( function(val){
console.log( val );
});
Add accumulated
and current
var sum = Rx.Observable
.of(1,2,3)
.do(function(){
console.log('Create side effects');
})
.scan(function(acc,curr) {
console.log('Curr', curr);
return acc + curr;
{ prop : ‘a’ }
{ prop : ‘a’, prop2 : ‘b’ }
1
3
6
Operators
transformation
Switch map,
complete something based on a condition
breakCondition = Rx.Observable.fromEvent(document,'click');
breakCondition.switchMap( function(val){
return Rx.Observable.interval(3000).mapTo('Do this if nothing breaks me');
})
breakCondition.subscribe( function(val){
console.log('Switch map', val);
})
Intended action is completed/restarted
by ‘breakCondition’
var sourceTiming = timingBreakCondition.switchMap( function(val){
return Rx.Observable.interval(1000).map(function(val){
return 'Emitting' + (val + 1);
})
})
sourceTiming.subscribe(function(val){
console.log('Switch map timer', val);
})
Operators
transformation
Emits 1,2 until it is restarted by
outer timer
Switch map
var timingBreakCondition = Rx.Observable.interval(3000);
Operators
transformation
var breakCondition = Rx.Observable.fromEvent(document,'click');
var source = breakCondition.switchMap( function(val){
return Rx.Observable.interval(3000).take(1)
.flatMap(function(){
return Rx.DOM.getJSON( 'data3.json' );
});
})
source.subscribe( function(val){
console.log('Switch map', val);
})
Get data every 3 second unless a ‘click’ happens
Switch map
Same example but do something useful like fetch data
flatMap
Takes an array of observables and
merges these into one meta stream
var stream= Rx.Observable
.fromArray([1,2,3,4])
.take(2)
.flatMap(function(val){
return Rx.Observable.interval(500).map(function(){
return val;
});
});
stream.subscribe(function(val){
console.log( val );
});
Creates observables
Will emit 1,2 in eternity
Operators
transformation
flatMap + json
var source = Rx.DOM.getJSON( 'data2.json' )
.flatMap( function(data) {
return Rx.Observable.fromArray( data ).map(function(row){
return row.props.name;
});
} );
source.subscribe( function(data){
console.log( data );
}) Takes array response
and emits it row by row
.flatMap( function(data) {
return Rx.Observable.fromArray( data ).pluck('props','name');
} );
.flatMap(Rx.Observable.fromArray).pluck('props','name')
Operators
transformation
1
2
3
Excellent to use when coming from
one stream to another
Operators
transformation
flatMap - example 2
flatmapExample = Rx.Observable.fromEvent(input,'keyup')
.map( function(ev){
return ev.target.value;
})
.filter(function(text){
return text.length >=3;
})
.distinctUntilChanged()
.flatMap( function(val){
return Rx.DOM.getJSON( 'data3.json' );
})
flatmapExample.subscribe( function(result){
console.log('Flatmap', result);
})
Transform event to char
Wait until we have 3 chars
Only perform search if this ‘search’ is unique
Error scenarios
Capture error in .subscribe()
Error handling catch
var errStream = Rx.Observable.throw('Error');
var stream = Rx.Observable.create(function(observer){
observer.onNext(1);
})
var merged = Rx.Observable
.merge( errStream, stream )
merged.subscribe( function(val){
console.log('Val', val);
}, function(err){
console.log('Err', err);
}, function(){
console.log('completed');
})
Captured here but sequence
interrupted,
completed NOT reached
Capture error in .subscribe() + completed stream
Error handling
Error handling improved catch
var errStream = Rx.Observable.throw('Error');
var stream = Rx.Observable.create(function(observer){
observer.onNext(1);
})
var merged = Rx.Observable
.merge( errStream, stream )
.catch(function(err){
return Rx.Observable.of(err);
});
merged.subscribe( function(val){
console.log('Val', val);
}, function(err){
console.log('Err', err);
}, function(){
console.log('completed');
})
Captured here but sequence
interrupted,
completed IS reached
stream not processed though
can we improve it?
Wrap error stream before merging with other streams
so we don’t kill other valid streams
Error handling
Error handling
ignoring
We need to handle the erroring stream better
From
var errStream = Rx.Observable
.throw('AAA thump..')
To
var errStream = Rx.Observable
.throw('AAA thump..')
.catch(function(err){
return Rx.Observable.of(err);
});
This will emit all values and the wrapped error
Process all values and errors by wrapping the errors,
everything gets processed
Error handling
Error - ignoring
other scenario
var merged = Rx.Observable
.merge( errStream2, stream )
merged.subscribe( function(val){
console.log('Val', val);
}, function(err){
console.log('Err', err);
}, function(){
console.log('completed');
})
1,1,2
var errStream2 = Rx.Observable
.interval(200)
.take(3)
.select(function(val){
if(val === 0) {
return Rx.Observable.throw('Error stream');
} else {
return Rx.Observable.of(val);
}
})
.select(function(observable){
return observable.catch(Rx.Observable.return('Error handled'));
})
.selectMany( function(x){
return x;
});
wrap
catch and rewrite
Set a policy for error handling of streams when merging so
successful stream survive
Error handling
Error - ignoring
other scenario
You have several sources and two terminates
You want the other normal source to work
var errStream = Rx.Observable
.throw('AAA thump..');
var errStreamWithFlattenedData = Rx.Observable
.interval(500)
.take(3)
.flatMap( function(val){
if( val === 1 ) {
return Rx.Observable.throw('crashing');
}
else {
return Rx.Observable.return(val);
}
})
var normalStream = Rx.Observable.return('anything');
var handledErrorStream =
Rx.Observable.onErrorResumeNext( errStream,
normalStream, errStreamWithFlattenedData );
handledErrorStream.subscribe(function(err){
console.log('error stream ignored', err);
},
function(err){
console.log("error stream ignored, error",err);
}, function(){
console.log("completion of error stream ignored");
})
Dies midstream though,
you probably want to handle it fully
Error - Retrying
var stream = Rx.DOM.get('/products.json').retry(5);
stream.subscribe((val) => {
console.log('Data', val);
}, err => console.log(err));
Good thing with a shaky connection
5 attemps are made until it comes as an error
Subject
Observer Observable
Subject
Inherits from both
the subject can act as a proxy for a group of subscribers and a source
Subject
example
var subject = new Rx.Subject();
subject.subscribe((val) => {
console.log( 'Produced by subject', val );
});
subject.onNext(1);
subject.onCompleted();
function Producer(){
this.i = 0;
}
Producer.prototype.nextValue = function(){
return i++;
}
var observable = new Rx.Observable((observer) => {
var producer = new Producer();
observer.onNext(producer.nextValue());
observer.onCompleted();
});
observable.subscribe( (val) => {
console.log('Normal observable')
});
Bold is usually an operator like
.of() or .interval()
Acts like a observer
Acts like an observable
Subject
var subject = new Rx.Subject();
var source = Rx.Observable.interval(500);
source.subscribe(subject);
subject.subscribe(
(val) => {
console.log('Sub', val);
},
(err) => console.log(err),
() => console.log('completed')
);
setTimeout(function() {
subject.onCompleted();
}, 3000);
Pass subject as an observer
Receives all the values pushed out by the source
Able to stop receiving values
Subject
proxy one stream and add to it
var subject = new Rx.Subject();
var source = Rx.Observable.interval(500).take(3);
source.subscribe( subject );
subject.subscribe((val) => {
console.log('Subject', val);
});
subject.onNext('Mess1');
subject.onNext('Mess2');
setTimeout(function() {
subject.onCompleted();
}, 1600);
Listens to all values from source
Add to stream
Order important
Subject
different types
AsyncSubject
Returns a single value IF it completes
Cached forever
Good for ajax requests
BehaviorSubject
Receives last emitted value
and then all subsequent ones
Good for a placeholder
then real data to replace it scenario
var subject = Rx.ReplaySubject();
subject.onNext(1);
subject.subscribe((val) = > {
console.log('Replay', val);
})
subject.onNext(2);
subject.onNext(3);
var subject = Rx.Subject();
subject.onNext(1);
subject.subscribe((val) = > {
console.log('Replay', val);
})
subject.onNext(2);
subject.onNext(3);
Subject
different types
Normal subject, everything before
subscribe is lost
Replay subject, nothing is lost
Schedulers
bending time
Schedulers
Is an operator async or sync?
Give you fine grained control over how an observable emits notifications
Does it block the event loop?
Can I control how notifications are emitted?
Scheduler
bend it like beckham
Switch from Rx.Scheduler.currentThread to Rx.Scheduler.default
var stream = Rx.Observable.of(1,2,3,4,5);
var now = new Date().getTime();
stream.subscribe(
(val) => {
console.log('Current thread')
},
err => {},
() => {
var done = new Date().getTime();
console.log( (done - now) + "ms" );
})
5ms
ar defaultStream = Rx.Observable.from([1,2,3,4,5],null,null,
Rx.Scheduler.default);
defaultStream.subscribe((val) => {
console.log('Default', val);
},
err => {},
() => {
var done = Date.now();
console.log( "default " + (done - now) + "ms" );
})
console.log('default');
This happens first
default is async 143ms !!
Scheduler
Use the right scheduler for the right things
Constant Time Operations => Rx.Scheduler.immediate
Tail Recursive Operations =>Rx.Scheduler.immediate
Iteration Operations => Rx.Scheduler.currentThread
Time-based Operations => Rx.Scheduler.default
Asynchronous Conversions => Rx.Scheduler.default
Historical Data Operations => Rx.HistoricalScheduler
Unit Testing => Rx.TestScheduler
Used right it can improve performance,
used wrong you will kill your app :)
Schedulers
testing
Because scheduler has its own virtual clock
Anything scheduled on that scheduler
will adhere to time denoted on the clock
I.e we can bend time for ex unit testing
Schedulers
testingvar onNext = Rx.ReactiveTest.onNext;
var scheduler = new Rx.TestScheduler();
var subject = scheduler.createColdObservable(
onNext(100,'first'),
onNext(200,'second')
);
var result;
subject.subscribe((val) => {
result = val;
});
scheduler.advanceBy( 100 );
console.log('Should equal', result === 'first');
scheduler.advanceBy( 100 );
console.log('Should equal', result === 'second');
What happens at what intervals
Advance time
Assert
Advance time
Assert
Schedulers
testing
var testScheduler = new Rx.TestScheduler();
var stream = Rx.Observable.interval(1000, testScheduler)
.take(5)
.map((val) => {
return val + 1
})
.filter((i) => {
return i % 2 === 0
});
var result;
stream.subscribe((val) => result = val );
console.log('testing function’);
testScheduler.advanceBy(1000);
testScheduler.advanceBy(1000);
testScheduler.advanceBy(1000);
console.log('Should equal', result === 2);
testScheduler.advanceBy(1000);
testScheduler.advanceBy(1000);
console.log('Should equal', result === 4);
We decide how fast time passes
Recipes
Buffer recipe, record interactions on UI
draw where the mouse has been
Replay a game, how a character have moved
left, right, jump, duck
Idea for a project, game where you get to play til you die
and take away move that kills you
Further reading
https://xgrommx.github.io/rx-book
http://www.learnrxjs.io/
Thank you

More Related Content

What's hot

Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
Christoffer Noring
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The Future
Tracy Lee
 
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
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett Welson
 
Angular 2 observables
Angular 2 observablesAngular 2 observables
Angular 2 observables
Geoffrey Filippi
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & Promises
Hùng Nguyễn Huy
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
L&T Technology Services Limited
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
Christoffer Noring
 
Les dessous du framework spring
Les dessous du framework springLes dessous du framework spring
Les dessous du framework spring
Antoine Rey
 
Asynchronous JavaScript Programming
Asynchronous JavaScript ProgrammingAsynchronous JavaScript Programming
Asynchronous JavaScript Programming
Haim Michael
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Module
arjun singh
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2
Knoldus Inc.
 
Callback Function
Callback FunctionCallback Function
Callback Function
Roland San Nicolas
 
React and redux
React and reduxReact and redux
React and redux
Mystic Coders, LLC
 
Action Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot ApplicationsAction Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot Applications
Joris Kuipers
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
Ignacio Martín
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
Max Huang
 
Angular directives and pipes
Angular directives and pipesAngular directives and pipes
Angular directives and pipes
Knoldus Inc.
 
React.js and Redux overview
React.js and Redux overviewReact.js and Redux overview
React.js and Redux overview
Alex Bachuk
 
Life Cycle hooks in VueJs
Life Cycle hooks in VueJsLife Cycle hooks in VueJs
Life Cycle hooks in VueJs
Squash Apps Pvt Ltd
 

What's hot (20)

Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The Future
 
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)
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Angular 2 observables
Angular 2 observablesAngular 2 observables
Angular 2 observables
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & Promises
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 
Les dessous du framework spring
Les dessous du framework springLes dessous du framework spring
Les dessous du framework spring
 
Asynchronous JavaScript Programming
Asynchronous JavaScript ProgrammingAsynchronous JavaScript Programming
Asynchronous JavaScript Programming
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Module
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2
 
Callback Function
Callback FunctionCallback Function
Callback Function
 
React and redux
React and reduxReact and redux
React and redux
 
Action Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot ApplicationsAction Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot Applications
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
 
Angular directives and pipes
Angular directives and pipesAngular directives and pipes
Angular directives and pipes
 
React.js and Redux overview
React.js and Redux overviewReact.js and Redux overview
React.js and Redux overview
 
Life Cycle hooks in VueJs
Life Cycle hooks in VueJsLife Cycle hooks in VueJs
Life Cycle hooks in VueJs
 

Similar to Rxjs ppt

Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
Christoffer Noring
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
Christoffer Noring
 
Rx – reactive extensions
Rx – reactive extensionsRx – reactive extensions
Rx – reactive extensions
Voislav Mishevski
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
Christoffer Noring
 
Rx workshop
Rx workshopRx workshop
Rx workshop
Ryan Riley
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
hezamu
 
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
 
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
Nikos Kalogridis
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiTech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Nexus FrontierTech
 
Reactive x
Reactive xReactive x
Reactive x
Gabriel Araujo
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
Tomasz Kowalczewski
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
Tomasz Kowalczewski
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
Rick Warren
 
RxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptRxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScript
Viliam Elischer
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
Shahar Barsheshet
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
Pratama Nur Wijaya
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstitute
Suresh Loganatha
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
Outware Mobile
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMixRxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMix
Tracy Lee
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 

Similar to Rxjs ppt (20)

Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Rx – reactive extensions
Rx – reactive extensionsRx – reactive extensions
Rx – reactive extensions
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
 
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)
 
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
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiTech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
 
Reactive x
Reactive xReactive x
Reactive x
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
RxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptRxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScript
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstitute
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMixRxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMix
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 

More from Christoffer Noring

Azure signalR
Azure signalRAzure signalR
Azure signalR
Christoffer Noring
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
Christoffer Noring
 
Game dev 101 part 2
Game dev 101   part 2Game dev 101   part 2
Game dev 101 part 2
Christoffer Noring
 
Game dev workshop
Game dev workshopGame dev workshop
Game dev workshop
Christoffer Noring
 
Deploying your static web app to the Cloud
Deploying your static web app to the CloudDeploying your static web app to the Cloud
Deploying your static web app to the Cloud
Christoffer Noring
 
IaaS with ARM templates for Azure
IaaS with ARM templates for AzureIaaS with ARM templates for Azure
IaaS with ARM templates for Azure
Christoffer Noring
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
Christoffer Noring
 
Ng spain
Ng spainNg spain
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
Christoffer Noring
 
Design thinking
Design thinkingDesign thinking
Design thinking
Christoffer Noring
 
Keynote ijs
Keynote ijsKeynote ijs
Keynote ijs
Christoffer Noring
 
Vue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and VuexVue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and Vuex
Christoffer Noring
 
Kendoui
KendouiKendoui
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
Christoffer Noring
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
Christoffer Noring
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
Christoffer Noring
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
Christoffer Noring
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
Christoffer Noring
 
React lecture
React lectureReact lecture
React lecture
Christoffer Noring
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
Christoffer Noring
 

More from Christoffer Noring (20)

Azure signalR
Azure signalRAzure signalR
Azure signalR
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
 
Game dev 101 part 2
Game dev 101   part 2Game dev 101   part 2
Game dev 101 part 2
 
Game dev workshop
Game dev workshopGame dev workshop
Game dev workshop
 
Deploying your static web app to the Cloud
Deploying your static web app to the CloudDeploying your static web app to the Cloud
Deploying your static web app to the Cloud
 
IaaS with ARM templates for Azure
IaaS with ARM templates for AzureIaaS with ARM templates for Azure
IaaS with ARM templates for Azure
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
 
Ng spain
Ng spainNg spain
Ng spain
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
Design thinking
Design thinkingDesign thinking
Design thinking
 
Keynote ijs
Keynote ijsKeynote ijs
Keynote ijs
 
Vue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and VuexVue fundamentasl with Testing and Vuex
Vue fundamentasl with Testing and Vuex
 
Kendoui
KendouiKendoui
Kendoui
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
React lecture
React lectureReact lecture
React lecture
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 

Recently uploaded

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
CAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on BlockchainCAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on Blockchain
Claudio Di Ciccio
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
Zilliz
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
David Brossard
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
Claudio Di Ciccio
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 

Recently uploaded (20)

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
CAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on BlockchainCAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on Blockchain
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 

Rxjs ppt

  • 1. RxJs - demystified Christoffer Noring @chris_noring Lodash for async
  • 3. What is reactive programming? Is a programming paradigm Focuses on propagating changes without us having to explicitly specify how the propagation happens State what our code should to without having to code every line
  • 4. Functional programming Avoid mutable state Avoid side-effects Functional composition over object composition = programs with predictable outcome
  • 5. Functional over imperative var list = [ 1,2,3,4,5 ]; var newList = list.map( function(value) { return value + 1; }) Produces a new list list NOT mutated/changed but projected Functional Imperative var list = [ 1,2,3,4,5 ]; list.forEach( function(value) { value += 1; }) X number invocation changes state
  • 6. Reactive programming Async data streams Turn click events user inputs data from server callbacks into a stream One paradigm/ api to rule them all
  • 7. Observable pattern Iterative pattern Observer Observable, observable sequence = Rx pattern Emits its values in order, like an iterator, BUT pushes values as they become available Has access to a producer in an observable pattern Push-based behaviour, don’t call us, we’ll call you Consumer of an observable Like listener in observable pattern Doesn’t start streaming unless it has at least one Observer subscribed to it
  • 8. At the heart of everything is the Observable
  • 9. Promise vs Array vs Observable list .map( x = > x.prop ) .filter( x => x > 2 ) .take( 2 ) list .map( x = > x.prop ) .filter( x => x > 2 ) .take( 2 ) .subscribe( x => console.log(x), ) Array Observable Promise service.get() .then( x => console.log(x) ) ) Array like, handles async but can also - Cancelled - Retried
  • 10. Observable vs Observable pattern function Producer(){ this.listeners = []; } Producer.prototype.add = function(listener){ this.listeners.push( listener ); } Producer.prototype.notify = function(message){ this.listeners.forEach( function(listener){ listener.update( message ); }) } var stream = new Rx.Observable(function(observer) { observer.onNext('message'); }) stream.subscribe( function(val){ console.log( val ); })
  • 11. Observable is usually NOT the producer, it has access to one though var stream = new Rx.Observable(function(observer){ var producer = new Producer(); producer.nextValue( function(val){ observer.onNext( val ); }) }) function Producer(){ } Producer.prototype.nextValue = function(cb){ setTimeout(function(){ cb( 1 ); },2000); } Producer created internally = “cold observable” Also responsible for emitting value to observer
  • 13. Marble diagrams Operation Stream Other stream Resulting stream 1 2 3 4 5 1 2 3 4 5 Most operators are covered at rxmarbles.com
  • 14. Observable with error var stream = Rx.Observable.create(function(observer){ observer.onNext(1); observer.onNext(2); observer.onNext(3); observer.onError( ‘there is an error’ ) }) stream.subscribe( function(data){ console.log( data ); }, function(error) { console.error( error ); } )
  • 15. Observable with completed var stream = Rx.Observable.create(function(observer){ observer.onNext( 1 ); observer.onNext( 2 ); observer.onNext( 3 ); observer.onCompleted(); }) stream.subscribe( function(data){ console.log( data ); }, function(error){ console.error( error ); }, function(){ console.info( “completed” ); } )
  • 16. Observable cancelling var homemadeStream = Rx.Observable.create((observer) => { var i=0; var handle = setInterval(function() { observer.onNext( i++ ); }, 500); return function(){ console.log('Disposing timeout'); clearTimeout( handle ); } }); var subscription2 = homemadeStream.subscribe((val) => { console.log('Homemade val',val); }); setTimeout(function() { console.log('Cancelling homemadeStream'); subscription2.dispose(); }, 1500); Define whats to happen on dispose Calling dispose Produce values till someone calls dispose
  • 17. Observable create your own var stream = Rx.Observable.create(function(observer){ observer.onNext(1); observer.onNext(2); observer.onNext(3); }) stream.subscribe( function(data){ console.log( data ); } ) Stream 1 2 3 onNext() onNext()
  • 18. Observable wrap ajax var stream = Rx.Observable.create(function(observer){ var request = new XMLHttpRequest(); request.open( ‘GET’, ‘url’ ); request.onload = function(){ if(request.status === 200) { observer.onNext( request.response ); observer.onCompleted(); } else { observer.onError( new Error( request.statusText ) ) } } request.onerror = function(){ observer.onError( new Error(‘unknown error’) ); } request.send(); }) stream.subscribe( function(result) { console.log( result ); } ) Producer
  • 19. Operators 120+ operators Combination Conditional Creational Error handling Multicasting Filtering Transformation Utility Categories
  • 21. Cold observable = producer is not shared var cold = new Observable((observer) => { var producer = new Producer(); // have observer listen to producer here }); var producer = new Producer(); var hot = new Observable((observer) => { // have observer listen to producer here }); A producer is the source of values for your observable. Operators multicasting
  • 22. Going from hot to cold Operators multicasting var stream = Rx.Observable.interval(1000); stream.subscribe(function(val){ console.log('Subscriber 1', val); }); stream.subscribe(function(val){ console.log('Subscriber 2', val); }); By definition cold, as both subscriber start from 0,1 .. NOT shared Subscriber 1 ,0 Subscriber 2 ,0 Starts on same number
  • 23. Operators multicasting How to share? stream.subscribe(function(val){ console.log('Subscriber 1', val); }); setTimeout(function() { stream.connect(); }, 2000); setTimeout(function() { stream.subscribe(function(val){ console.log('Started after 4 sec, Subscriber 2', val); }); }, 4000); var stream = Rx.Observable.interval(1000) .publish(); Sits and wait til
  • 24. Observable, creating Rx.Observable.fromArray([ 1,2,3,4 ]) Rx.Observable.fromEvent(element, ‘event’); Rx.Observable.fromArray(eventEmitter, ‘data’, function(){}) Rx.Observable.fromNodeCallback(fs.createFile) Rx.Observable.fromCallback(obj.callback) Rx.Observable.fromPromise(promise) Rx.Observable.fromIterable(function *() { yield 20 }) Rx.Observable.range(1,3) Rx.Observable.interval(miliseconds)
  • 25. Observable common operators var stream = Rx.Observable.of(1,2,3,4,5); stream.map((val) => { return val + 1; }) .filter((val) => { return val % 3 === 0; }) Investigates every value
  • 26. Observable reducer var stream2 = Rx.Observable.of(1,2,3,4,5,6); var subscription2 = stream2.reduce((acc, curr) => { return acc + curr; }); subscription2.subscribe((val) => { console.log('Sum', val); })
  • 28. Operators utility var stream = Rx.Observable.of(1,2,3,4,5); var subscription = stream .do(function(val){ console.log('Current val', val); }) .filter(function(val){ return val % 2 === 0; }); subscription.subscribe(function(val){ console.log('Val',val); }) Echos every value without changing it, used for logging Do
  • 29. Operators utility toPromise Used to create a promise from an observable stream .filter(function(val){ return val % 2 === 0; }) .toPromise() .then( function(val){ console.log('Promise', val); }) 4 var stream = Rx.Observable.of(1,2,3,4,5); Only latest value that fulfils filter is returned
  • 30. Operators utility let stream .let( observable => observable .filter(function(x){ return x % 2 > 0; })) .take(2) .subscribe(function(val){ console.log('let', val); }) Let’s us operate on the observable. We don’t need to return what we do like with a normal operator stream .filter(function(val){ return val % 2 === 0; }) var stream = Rx.Observable.of(1,2,3,4,5);
  • 31. Operators utilityDelay, the whole sequence stream .delay(1000) .subscribe( (val) => { var newTime = new Date().getTime(); console.log('Delayed', val + " " + (newTime - time)); }) Rx.Observable.merge( Rx.Observable.of('Marco').delay(1000), Rx.Observable.of('Polo').delay(2000) ).subscribe((val) => { var newTime = new Date().getTime(); console.log('Merged Delay', val + " " + (newTime - time)); }) ….. 1 second 1 2 3 ….. 1 second Marco ….. 2 second Polo
  • 33. Operators combination concat merge var concat = Rx.Observable.concat( stream, stream2 ); var stream = Rx.Observable.fromArray([1,2,3,4]); var stream2 = Rx.Observable.fromArray([5,6,7,8]); 1, 2, 3, 4, 5, 6, 7 ,8 var merge = Rx.Observable.merge( stream, stream2 ); 1, 5, 2, 6, 3, 7, 4 ,8 first stream emits all values then remaining value streams take turn There is difference so choose wisely
  • 34. Operators combination var stream = Rx.Observable.fromArray([1,2,3,4]); var stream2 = Rx.Observable.fromArray([5,6,7,8]); var combineLatest = Rx.Observable.combineLatest( stream, stream2 ); combineLatest.subscribe( function(val) { console.log( 'combine ', val ) }) combineLatest [1,5], [2,6], [3,7], [4,8]
  • 36. Operators conditional var stream = Rx.Observable .fromArray([1,2,3,4]) .every( function(val){ return val % 2 === 0; }); false var evenStream = Rx.Observable .fromArray([2,4,8]) .every( function(val){ return val % 2 === 0 }); true Condition needs to be fulfilled on all values
  • 38. Operators filtering var debounceTime = Rx.Observable .fromEvent(button,'click') .debounce(2000); debounceTime.subscribe( function(){ console.log('mouse pressed'); }) waits x ms and returns latest emitted var debouncedStream = Rx.Observable .fromArray([1,2]) .debounce(25); debouncedStream.subscribe( function(val){ console.log('debounce stream', val ); }); returns 2 ex1 ex2 Ignores all generated mouse click events for 2 seconds
  • 39. Operators filtering var mousePressedTimer = Rx.Observable.interval(1000); mousePressedTimer .takeUntil( mouseUp ) .subscribe( function(val){ console.log('mouse up has NOT happened yet',val); }, function(err){}, function(){ console.log('condition fulfilled'); }) var mouseUp = Rx.Observable.fromEvent(button,'mouseup'); Break condition Generate numbers
  • 40. var throttle = Rx.Observable .interval( 1000 ) .throttle( 1000 ); throttle.subscribe( function(val){ console.log('Throttle', val ); }); Operators filtering Delay every value by x milliseconds Throttle 1 2 3 4 1 2
  • 42. Operators transformation var numbers = Rx.Observable.interval(1000); var bufferBy = Rx.Observable.fromEvent(document,'click'); var buffered = numbers.buffer( bufferBy ); buffered.subscribe(function(values){ console.log('Buffered',values); }); [1,2] [3,4,5,6,7] etc… Numbers are generated to a buffer until condition is met, then the buffer content is emitted Buffer
  • 43. Operators transformation var bufferTime = numbers.bufferTime(2000); bufferTime.subscribe(function(values){ console.log("Buffer time",values); }) var numbers = Rx.Observable.interval(1000); Waits x miliseconds and then emits buffer BufferTime
  • 44. var expand = Rx.Observable .of(2) .expand(function(val){ return Rx.Observable.of(1 + val); }) .take(3); expand.subscribe(function(val){ console.log('Expand',val); }) Operators transformationExpand Recursively call provided callback x times
  • 45. Operators transformation Scan var scanning = Rx.Observable .of({ prop : 'a'}, { prop2 : 'b'}) .scan((acc, curr) => Object.assign({}, acc, curr), {}); scanning.subscribe( function(val){ console.log( val ); }); Add accumulated and current var sum = Rx.Observable .of(1,2,3) .do(function(){ console.log('Create side effects'); }) .scan(function(acc,curr) { console.log('Curr', curr); return acc + curr; { prop : ‘a’ } { prop : ‘a’, prop2 : ‘b’ } 1 3 6
  • 46. Operators transformation Switch map, complete something based on a condition breakCondition = Rx.Observable.fromEvent(document,'click'); breakCondition.switchMap( function(val){ return Rx.Observable.interval(3000).mapTo('Do this if nothing breaks me'); }) breakCondition.subscribe( function(val){ console.log('Switch map', val); }) Intended action is completed/restarted by ‘breakCondition’
  • 47. var sourceTiming = timingBreakCondition.switchMap( function(val){ return Rx.Observable.interval(1000).map(function(val){ return 'Emitting' + (val + 1); }) }) sourceTiming.subscribe(function(val){ console.log('Switch map timer', val); }) Operators transformation Emits 1,2 until it is restarted by outer timer Switch map var timingBreakCondition = Rx.Observable.interval(3000);
  • 48. Operators transformation var breakCondition = Rx.Observable.fromEvent(document,'click'); var source = breakCondition.switchMap( function(val){ return Rx.Observable.interval(3000).take(1) .flatMap(function(){ return Rx.DOM.getJSON( 'data3.json' ); }); }) source.subscribe( function(val){ console.log('Switch map', val); }) Get data every 3 second unless a ‘click’ happens Switch map Same example but do something useful like fetch data
  • 49. flatMap Takes an array of observables and merges these into one meta stream var stream= Rx.Observable .fromArray([1,2,3,4]) .take(2) .flatMap(function(val){ return Rx.Observable.interval(500).map(function(){ return val; }); }); stream.subscribe(function(val){ console.log( val ); }); Creates observables Will emit 1,2 in eternity Operators transformation
  • 50. flatMap + json var source = Rx.DOM.getJSON( 'data2.json' ) .flatMap( function(data) { return Rx.Observable.fromArray( data ).map(function(row){ return row.props.name; }); } ); source.subscribe( function(data){ console.log( data ); }) Takes array response and emits it row by row .flatMap( function(data) { return Rx.Observable.fromArray( data ).pluck('props','name'); } ); .flatMap(Rx.Observable.fromArray).pluck('props','name') Operators transformation 1 2 3
  • 51. Excellent to use when coming from one stream to another Operators transformation flatMap - example 2 flatmapExample = Rx.Observable.fromEvent(input,'keyup') .map( function(ev){ return ev.target.value; }) .filter(function(text){ return text.length >=3; }) .distinctUntilChanged() .flatMap( function(val){ return Rx.DOM.getJSON( 'data3.json' ); }) flatmapExample.subscribe( function(result){ console.log('Flatmap', result); }) Transform event to char Wait until we have 3 chars Only perform search if this ‘search’ is unique
  • 52. Error scenarios Capture error in .subscribe()
  • 53. Error handling catch var errStream = Rx.Observable.throw('Error'); var stream = Rx.Observable.create(function(observer){ observer.onNext(1); }) var merged = Rx.Observable .merge( errStream, stream ) merged.subscribe( function(val){ console.log('Val', val); }, function(err){ console.log('Err', err); }, function(){ console.log('completed'); }) Captured here but sequence interrupted, completed NOT reached
  • 54. Capture error in .subscribe() + completed stream Error handling
  • 55. Error handling improved catch var errStream = Rx.Observable.throw('Error'); var stream = Rx.Observable.create(function(observer){ observer.onNext(1); }) var merged = Rx.Observable .merge( errStream, stream ) .catch(function(err){ return Rx.Observable.of(err); }); merged.subscribe( function(val){ console.log('Val', val); }, function(err){ console.log('Err', err); }, function(){ console.log('completed'); }) Captured here but sequence interrupted, completed IS reached stream not processed though can we improve it?
  • 56. Wrap error stream before merging with other streams so we don’t kill other valid streams Error handling
  • 57. Error handling ignoring We need to handle the erroring stream better From var errStream = Rx.Observable .throw('AAA thump..') To var errStream = Rx.Observable .throw('AAA thump..') .catch(function(err){ return Rx.Observable.of(err); }); This will emit all values and the wrapped error
  • 58. Process all values and errors by wrapping the errors, everything gets processed Error handling
  • 59. Error - ignoring other scenario var merged = Rx.Observable .merge( errStream2, stream ) merged.subscribe( function(val){ console.log('Val', val); }, function(err){ console.log('Err', err); }, function(){ console.log('completed'); }) 1,1,2 var errStream2 = Rx.Observable .interval(200) .take(3) .select(function(val){ if(val === 0) { return Rx.Observable.throw('Error stream'); } else { return Rx.Observable.of(val); } }) .select(function(observable){ return observable.catch(Rx.Observable.return('Error handled')); }) .selectMany( function(x){ return x; }); wrap catch and rewrite
  • 60. Set a policy for error handling of streams when merging so successful stream survive Error handling
  • 61. Error - ignoring other scenario You have several sources and two terminates You want the other normal source to work var errStream = Rx.Observable .throw('AAA thump..'); var errStreamWithFlattenedData = Rx.Observable .interval(500) .take(3) .flatMap( function(val){ if( val === 1 ) { return Rx.Observable.throw('crashing'); } else { return Rx.Observable.return(val); } }) var normalStream = Rx.Observable.return('anything'); var handledErrorStream = Rx.Observable.onErrorResumeNext( errStream, normalStream, errStreamWithFlattenedData ); handledErrorStream.subscribe(function(err){ console.log('error stream ignored', err); }, function(err){ console.log("error stream ignored, error",err); }, function(){ console.log("completion of error stream ignored"); }) Dies midstream though, you probably want to handle it fully
  • 62. Error - Retrying var stream = Rx.DOM.get('/products.json').retry(5); stream.subscribe((val) => { console.log('Data', val); }, err => console.log(err)); Good thing with a shaky connection 5 attemps are made until it comes as an error
  • 63. Subject Observer Observable Subject Inherits from both the subject can act as a proxy for a group of subscribers and a source
  • 64. Subject example var subject = new Rx.Subject(); subject.subscribe((val) => { console.log( 'Produced by subject', val ); }); subject.onNext(1); subject.onCompleted(); function Producer(){ this.i = 0; } Producer.prototype.nextValue = function(){ return i++; } var observable = new Rx.Observable((observer) => { var producer = new Producer(); observer.onNext(producer.nextValue()); observer.onCompleted(); }); observable.subscribe( (val) => { console.log('Normal observable') }); Bold is usually an operator like .of() or .interval() Acts like a observer Acts like an observable
  • 65. Subject var subject = new Rx.Subject(); var source = Rx.Observable.interval(500); source.subscribe(subject); subject.subscribe( (val) => { console.log('Sub', val); }, (err) => console.log(err), () => console.log('completed') ); setTimeout(function() { subject.onCompleted(); }, 3000); Pass subject as an observer Receives all the values pushed out by the source Able to stop receiving values
  • 66. Subject proxy one stream and add to it var subject = new Rx.Subject(); var source = Rx.Observable.interval(500).take(3); source.subscribe( subject ); subject.subscribe((val) => { console.log('Subject', val); }); subject.onNext('Mess1'); subject.onNext('Mess2'); setTimeout(function() { subject.onCompleted(); }, 1600); Listens to all values from source Add to stream Order important
  • 67. Subject different types AsyncSubject Returns a single value IF it completes Cached forever Good for ajax requests BehaviorSubject Receives last emitted value and then all subsequent ones Good for a placeholder then real data to replace it scenario
  • 68. var subject = Rx.ReplaySubject(); subject.onNext(1); subject.subscribe((val) = > { console.log('Replay', val); }) subject.onNext(2); subject.onNext(3); var subject = Rx.Subject(); subject.onNext(1); subject.subscribe((val) = > { console.log('Replay', val); }) subject.onNext(2); subject.onNext(3); Subject different types Normal subject, everything before subscribe is lost Replay subject, nothing is lost
  • 70. Schedulers Is an operator async or sync? Give you fine grained control over how an observable emits notifications Does it block the event loop? Can I control how notifications are emitted?
  • 71. Scheduler bend it like beckham Switch from Rx.Scheduler.currentThread to Rx.Scheduler.default var stream = Rx.Observable.of(1,2,3,4,5); var now = new Date().getTime(); stream.subscribe( (val) => { console.log('Current thread') }, err => {}, () => { var done = new Date().getTime(); console.log( (done - now) + "ms" ); }) 5ms ar defaultStream = Rx.Observable.from([1,2,3,4,5],null,null, Rx.Scheduler.default); defaultStream.subscribe((val) => { console.log('Default', val); }, err => {}, () => { var done = Date.now(); console.log( "default " + (done - now) + "ms" ); }) console.log('default'); This happens first default is async 143ms !!
  • 72. Scheduler Use the right scheduler for the right things Constant Time Operations => Rx.Scheduler.immediate Tail Recursive Operations =>Rx.Scheduler.immediate Iteration Operations => Rx.Scheduler.currentThread Time-based Operations => Rx.Scheduler.default Asynchronous Conversions => Rx.Scheduler.default Historical Data Operations => Rx.HistoricalScheduler Unit Testing => Rx.TestScheduler Used right it can improve performance, used wrong you will kill your app :)
  • 73. Schedulers testing Because scheduler has its own virtual clock Anything scheduled on that scheduler will adhere to time denoted on the clock I.e we can bend time for ex unit testing
  • 74. Schedulers testingvar onNext = Rx.ReactiveTest.onNext; var scheduler = new Rx.TestScheduler(); var subject = scheduler.createColdObservable( onNext(100,'first'), onNext(200,'second') ); var result; subject.subscribe((val) => { result = val; }); scheduler.advanceBy( 100 ); console.log('Should equal', result === 'first'); scheduler.advanceBy( 100 ); console.log('Should equal', result === 'second'); What happens at what intervals Advance time Assert Advance time Assert
  • 75. Schedulers testing var testScheduler = new Rx.TestScheduler(); var stream = Rx.Observable.interval(1000, testScheduler) .take(5) .map((val) => { return val + 1 }) .filter((i) => { return i % 2 === 0 }); var result; stream.subscribe((val) => result = val ); console.log('testing function’); testScheduler.advanceBy(1000); testScheduler.advanceBy(1000); testScheduler.advanceBy(1000); console.log('Should equal', result === 2); testScheduler.advanceBy(1000); testScheduler.advanceBy(1000); console.log('Should equal', result === 4); We decide how fast time passes
  • 76. Recipes Buffer recipe, record interactions on UI draw where the mouse has been Replay a game, how a character have moved left, right, jump, duck Idea for a project, game where you get to play til you die and take away move that kills you