SlideShare una empresa de Scribd logo
1 de 58
Rxjs
everything is a stream
Christoffer Noring
Google Developer Expert
@chris_noring
Why Rxjs?
We want to deal with async in a “synchronous looking way”
We want something better than promises
We want one paradigm for async to rule them all
nce upon a time in async land
There were callbacks
Callbacks turned into callback hell
Promises to the rescue
service
.getData()
.then(getMoreData)
.then(getEvenMore)
.then(andSomeMore)
Looks great right?
But promises were flawed
No cancellation
eal with other async concepts like mouse positions, clicks, use
No rich composition
And brexit happened
Cumbersome to retry
Only returns one value
Help us Observables
You’re my only hope
What is an observable
Observable is just a function
that takes an observer and returns a function
Observer: an object with next, error, complete methods
Rx.Observable.create((observer) => {
observer.next(1);
observer.error(‘error’);
observer.complete();
})
1 2 3 4 5 6 7
stream of value over time
Promise
vs Array
vs Observable
list
.map( x = > x.prop )
.filter( x => x > 2 )
.take( 2 )
Array
list
.map( x = > x.prop )
.filter( x => x > 2 )
.take( 2 )
.subscribe(
x => console.log(x),
err => console.log(err) )
Observable
Promise
service.get()
.then( x => console.log(x) )
.catch( err => console.log(err) ) but can also
- Cancelled
- Retried
Array like,
handles async
So pretty much linq with
async
Rx.Observable.create(
fnValue,,
fnError,,
fnCompleted
)
Observable signature
var stream = Rx.Observable.create((observer) =>{
})})
Emits
stream
.subscribe(
(data) => { console.log( data ); }
)
1
next()
observer.next(1);
2
next()
observer.next(2);
3
next()
observer.next(3);
var stream = Rx.Observable.create((observer) =>{
})
stream
.subscribe(
(data) => { console.log( data ); }
(err) => { console.log(err); }
)
Emits 1
next()
observer.next(1);
error message
error()
observer.error(‘something went wrong’)
var stream = Rx.Observable.create((observer) =>{
})})
stream
.subscribe(
(data) => { console.log( data ); }
(err) => { console.log(err) },
() => { console.log(‘completed’) }
)
Emits 1
next()
observer.next(1);
complete()
observer.complete();
Cancelling
.unsubscribe()
var homemadeStream = Rx.Observable.create((observer) => {
var i=0;
});
var subscription2 = homemadeStream.subscribe((val) => {
console.log('Homemade val',val);
});
setTimeout(() => {
console.log('Cancelling homemadeStream');
subscription2.unsubscribe();
}, 1500); Calling dispose
Produce values
till someone calls unsubscribe
var handle = setInterval(() => {
observer.next( i++ );
}, 500);
Define whats to happen
on unsubscribe
return function(){
console.log('Disposing timeout');
clearTimeout( handle );
}
You will always create
an observable from something
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)
Wrap an observable
next()
error()
complete()
var stream = Rx.Observable.create((observer) => {
var request = new XMLHttpRequest();
request.open( ‘GET’, ‘url’ );
request.onload =() =>{
if(request.status === 200) {
} else {
}
}
request.onerror = () => { }
request.send();
})
stream.subscribe(
)
observer.next( request.response );
(result) => { console.log( result ); }
Get our data
observer.complete();
() => { console.log(‘completed’); }
No more data, close stream
observer.error( new Error( request.statusText ) )
(err) => { console.log(err) },
observer.error( new Error(‘unknown error’) );
Error
Error
Hot vs Cold Observable
Cold Observable
recorded tv show
Hot observable
Live streaming
eg World Cup Final
Observables are cold by default,
unless you make them hot
var stream = Rx.Observable.interval(1000);
stream.subscribe(
(val) => { console.log('Subscriber 1', val);}
);
stream.subscribe(
(val) => { console.log('Subscriber 2', val); }
);
var stream = Rx.Observable
.interval(1000)
.publish();
stream.subscribe((val) => {
console.log('Subscriber 1', val);
});
setTimeout(function() {
stream.connect();
}, 2000);
setTimeout(() => {
stream.subscribe((val) => {
console.log('Value', val);
});
}, 4000);
Subscriber 2 Values 0 1 2 3 4
Subscriber 1 Values 0 1 2 3 4
0 1 2 3 4 5 6
3 4 5 6
You can create an observable
from almost any async concept
Operators however gives it
its power
Remember:
But:
Operators
makes your code look like linq
120+ operators Rxjs 4
60+ Rxjs 5
Combination
Conditional
Multicasting
Filtering
Transformation
Utility
Categories
in production
Marble diagram
how does that operator work
Operator
Most operators are covered at rxmarbles.com
Stream 1 2 3
Other stream 4 5
Resulting stream 1 2 3 4 5
Operator example
var stream = Rx.Observable.of(1,2,3,4,5);
stream
stream.subscribe((data) => { console.log(‘data’); })
Operators :
map()
filter()
3
Emits
6
.map((val) => {
return val + 1;
})
changes the value
.filter((val) => {
return val % 3 === 0;
})
filters out values
Do
var stream = Rx.Observable.of(1,2,3,4,5);
var subscription = stream
.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((val) => {
console.log('Current val', val);
})
Current val 1
Current val 2
Current val 3
Current val 4
Current val 5
Subscribe:
2
4
debounce
var debounceTime = Rx.Observable
.fromEvent(button,'click')
debounceTime.subscribe( function(){
console.log('mouse pressed');
})
waits x ms and
returns latest emitted
Ignores all generated
mouse click events
for 2 seconds.debounce(2000);
Clicking save button
2secclick click click click click
save()
switchMap
Switch map,
complete something based on a condition
breakCondition = Rx.Observable.fromEvent(document,'click');
breakCondition.switchMap((val) => {
return Rx.Observable.interval(3000).mapTo(‘Do this');
})
breakCondition.subscribe((val) => {
console.log('Switch map', val);
})
Intended action is completed/restarted
by ‘breakCondition’
etc..
Do this
Do this
Do this
Do this
Do this
click
click
source.subscribe((data) => {
console.log( data );
})
flatMap
let source = Rx.DOM.getJSON( 'data2.json' )
return Rx.Observable.fromArray( data ).map((row) => {
return row.props.name;
});
return observable
.flatMap((data) => {
} );
We get an array response that we want to emit row by row
We use flatMap instead of map because :
We want to flatten our list to one stream
flatMap explained
when you create a list of observables flatMap flattens that list s
Great when changing from one type of stream to another
Without it you would have to listen to every single substream, w
eve
nt
eve
nt
eve
nt
eve
nt
ajax ajax ajax ajax
json json json json
flatMap
map
Problem : Autocomplete
Listen for keyboard presses
Filter so we only do server trip after x number of
chars are entered
Do ajax call based on filtered input
Cash responses,
don’t do unnecessary calls to http server
The procedural approach
let input = $(‘#input’);
input.bind(‘keyup’,() = >{
let val = input.val()
if(val.length >= 3 ) {
if( isCached( val ) ) { buildList( getFromCache(val) ); return; }
doAjax( val ).then( (response) => {
buildList( response.json() )
storeInCache( val, response.json() )
});
}
})
fetch if x characters long
return if cached
do ajax
Ok solution but NOT so fluent
We need 3 methods to deal with cache
The observable approach
Stream modeling
key key key key key key
FILTER
AJAX CALL
jso
n
jso
n
MAP
key key key key key key key
respons
e
respons
e
flatmapExample = Rx.Observable.fromEvent(input,'keyup')
flatmapExample.subscribe(
(result) =>{ console.log('Flatmap', result); buildList( result ) }
)
more fluent
Transform event to char.map((ev) => {
return ev.target.value;
})
Wait until we have 3 chars
.filter(function(text){
return text.length >=3;
})
Only perform search if this ‘search’ is unique.distinctUntilChanged()
Excellent to use when
coming from
one stream to another
.switchMap((val) => {
return Rx.DOM.getJSON( 'data3.json' );
})
Error handling
when streams fail
error
completion
.catch() completion
completion
no values
completion
values, WIN!
.catch()
merge
.catch()
merge
onErrorResumeNext
completion
values, WIN
error
completion
no values
retry
let stream = Rx.Observable.interval(1000)
.take(6);
.map((n) => {
if(n === 2) {
throw 'ex';
}
return n;
})
Produce error
.retry(2)
Number of tries
before hitting error callback
stream.subscribe(
(data) => console.log(data)
(error) => console.log(error)
1
Emits
3
Makes x attempts before error cb is called
retryWhen
delay between attempts
let stream = Rx.Observable.interval(1000)
.take(6);
delay, 200 ms.retryWhen((errors) => {
return errors.delay(200);
})
.map((n) => {
if(n === 2) {
throw 'ex';
}
return n;
})
produce an error when
= 2
stream.subscribe(
(data) => console.log(data)
(error) => console.log(error) for those shaky connections
What did we learn so far?
We can cancel with .unsubsribe()
We can retry easily
A stream generates a continuous stream of values
Operators manipulate either the values or the stream/s
We can “patch” an erronous stream with a .catch()
or
Ignore a failing stream altogether
with onErrorResumeNext
Schedulers
bending time
What about schedulers and
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 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);
console.log('Should equal', result === 4);
increment operator
testScheduler.advanceBy(1000);
testScheduler.advanceBy(1000);
testScheduler.advanceBy(1000);
assert
console.log('Should equal', result === 2);
Comparing promises
to Rxjs
.then vs .subscribe
getData()
.then(
)
getData().subscribe(
)
I will keep on streaming values
(data) => console.log(data),
(data) => console.log(data),
(err) => console.log(err) (err) => console.log(err)
user
order
orderItem
Fetch user
Then fetch order
Lastly fetch order item
Cascading calls
Response:
//getUser
stream
.subscribe((orderItem) => {
console.log('OrderItem',orderItem.id);
})
{ id: 11, userId : 1 }.then(getOrderByUser)
.switchMap((user) => {
//getOrder
return Rx.Observable.of({ id : 11, userId : user.id }).delay(3000)
})
{ id: 123, orderId : 11 }.then(getOrderItemByOrder)
.switchMap((order) => {
//getOrderItem
return Rx.Observable.of({ id: 114, orderId: order.id })
})
{ id: 1 }getUser()
var stream = Rx.Observable.of({ id : 1 });
So we can see the
first user observable
being dropped when
user 2 is emitted
Short word on switchMap
is to ensure we throw away the other calls when a new user is em
We don’t want
getUser
getOrderByUser
getOrderItemByOrder
to complete if a new user is emitted
1 2 3
2 4 5
Not continued
Replaces above
stream
user
orders messages
Fetch user
Fetch in parallell
Cascading call
wait for the first
.subscribe(
(data) => {
console.log( 'orders', data[0] );
console.log( 'messages', data[0] );
}
)
var stream = Rx.Observable.of([{ id : 1 }, { id : 2 }]);
getUser()
We wait for user
function getOrdersAndMessages(user){
return Promise.all([
getOrdersByUser( user.id ),
getMessagesByUser( user.id )
])
}
.then(getOrdersAndMessages)
stream.switchMap((user) => {
return Rx.Observable.forkJoin(
Rx.Observable.of([ { id: 1, userId : user.id } ]).delay(500), // orders
Rx.Observable.of([ { id: 100, userId : user.id } ]).delay(1500) //messages
)
})
Calls to orders and message
can happen in parallel
Orders,Messages
arrive at the same time
Last summary
We can use schedulers to easily test our code
Cascading calls can easily be setup
switchMap over flatMap when doing ajax calls
because we need it to abandon the stream if
the first condition change
Rxjs
An elegant weapon for a
more civilized age
Remember..
Thank you

Más contenido relacionado

La actualidad más candente

Introduction to Linked Data 1/5
Introduction to Linked Data 1/5Introduction to Linked Data 1/5
Introduction to Linked Data 1/5
Juan Sequeda
 

La actualidad más candente (20)

Angular Observables & RxJS Introduction
Angular Observables & RxJS IntroductionAngular Observables & RxJS Introduction
Angular Observables & RxJS Introduction
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Introduction to Linked Data 1/5
Introduction to Linked Data 1/5Introduction to Linked Data 1/5
Introduction to Linked Data 1/5
 
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)
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The Future
 
Web Worker, Service Worker and Worklets
Web Worker, Service Worker and WorkletsWeb Worker, Service Worker and Worklets
Web Worker, Service Worker and Worklets
 
Going realtime with Socket.IO
Going realtime with Socket.IOGoing realtime with Socket.IO
Going realtime with Socket.IO
 
Swagger
SwaggerSwagger
Swagger
 
Introducing Async/Await
Introducing Async/AwaitIntroducing Async/Await
Introducing Async/Await
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
REST API and CRUD
REST API and CRUDREST API and CRUD
REST API and CRUD
 
Angular Directives | Angular 2 Custom Directives | Angular Tutorial | Angular...
Angular Directives | Angular 2 Custom Directives | Angular Tutorial | Angular...Angular Directives | Angular 2 Custom Directives | Angular Tutorial | Angular...
Angular Directives | Angular 2 Custom Directives | Angular Tutorial | Angular...
 
Modern JS with ES6
Modern JS with ES6Modern JS with ES6
Modern JS with ES6
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Enabling Googley microservices with HTTP/2 and gRPC.
Enabling Googley microservices with HTTP/2 and gRPC.Enabling Googley microservices with HTTP/2 and gRPC.
Enabling Googley microservices with HTTP/2 and gRPC.
 
Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android application
 
Swagger UI
Swagger UISwagger UI
Swagger UI
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
 

Destacado

Developing components and extensions for ext js
Developing components and extensions for ext jsDeveloping components and extensions for ext js
Developing components and extensions for ext js
Mats Bryntse
 
ReactiveX-SEA
ReactiveX-SEAReactiveX-SEA
ReactiveX-SEA
Yang Yang
 

Destacado (20)

React lecture
React lectureReact lecture
React lecture
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJS
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
 
Reactive Programming and RxJS
Reactive Programming and RxJSReactive Programming and RxJS
Reactive Programming and RxJS
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Extjs presentation
Extjs presentationExtjs presentation
Extjs presentation
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Developing components and extensions for ext js
Developing components and extensions for ext jsDeveloping components and extensions for ext js
Developing components and extensions for ext js
 
The Ext JS 4 Layout System
The Ext JS 4 Layout SystemThe Ext JS 4 Layout System
The Ext JS 4 Layout System
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 
Finjs - Angular 2 better faster stronger
Finjs - Angular 2 better faster strongerFinjs - Angular 2 better faster stronger
Finjs - Angular 2 better faster stronger
 
Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Rethink Async With RXJS
Rethink Async With RXJSRethink Async With RXJS
Rethink Async With RXJS
 
FRP with Ractive and RxJS
FRP with Ractive and RxJSFRP with Ractive and RxJS
FRP with Ractive and RxJS
 
ReactiveX-SEA
ReactiveX-SEAReactiveX-SEA
ReactiveX-SEA
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Apps
 
Programação reativa com RxJS e Angular
Programação reativa com RxJS e AngularProgramação reativa com RxJS e Angular
Programação reativa com RxJS e Angular
 

Similar a Rxjs ngvikings

rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
Alexander Mostovenko
 

Similar a Rxjs ngvikings (20)

Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
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
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
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
 
RxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptRxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScript
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
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
 
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)
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
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
 
Rx – reactive extensions
Rx – reactive extensionsRx – reactive extensions
Rx – reactive extensions
 

Más de Christoffer Noring

Más de Christoffer Noring (19)

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
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 
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
 
Nativescript with angular 2
Nativescript with angular 2Nativescript with angular 2
Nativescript with angular 2
 

Último

Último (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 

Rxjs ngvikings

  • 1. Rxjs everything is a stream Christoffer Noring Google Developer Expert @chris_noring
  • 2. Why Rxjs? We want to deal with async in a “synchronous looking way” We want something better than promises We want one paradigm for async to rule them all
  • 3. nce upon a time in async land There were callbacks Callbacks turned into callback hell
  • 4. Promises to the rescue service .getData() .then(getMoreData) .then(getEvenMore) .then(andSomeMore) Looks great right?
  • 5. But promises were flawed No cancellation eal with other async concepts like mouse positions, clicks, use No rich composition And brexit happened Cumbersome to retry Only returns one value
  • 7. What is an observable Observable is just a function that takes an observer and returns a function Observer: an object with next, error, complete methods Rx.Observable.create((observer) => { observer.next(1); observer.error(‘error’); observer.complete(); }) 1 2 3 4 5 6 7 stream of value over time
  • 8. Promise vs Array vs Observable list .map( x = > x.prop ) .filter( x => x > 2 ) .take( 2 ) Array list .map( x = > x.prop ) .filter( x => x > 2 ) .take( 2 ) .subscribe( x => console.log(x), err => console.log(err) ) Observable Promise service.get() .then( x => console.log(x) ) .catch( err => console.log(err) ) but can also - Cancelled - Retried Array like, handles async
  • 9. So pretty much linq with async
  • 11. var stream = Rx.Observable.create((observer) =>{ })}) Emits stream .subscribe( (data) => { console.log( data ); } ) 1 next() observer.next(1); 2 next() observer.next(2); 3 next() observer.next(3);
  • 12. var stream = Rx.Observable.create((observer) =>{ }) stream .subscribe( (data) => { console.log( data ); } (err) => { console.log(err); } ) Emits 1 next() observer.next(1); error message error() observer.error(‘something went wrong’)
  • 13. var stream = Rx.Observable.create((observer) =>{ })}) stream .subscribe( (data) => { console.log( data ); } (err) => { console.log(err) }, () => { console.log(‘completed’) } ) Emits 1 next() observer.next(1); complete() observer.complete();
  • 15. var homemadeStream = Rx.Observable.create((observer) => { var i=0; }); var subscription2 = homemadeStream.subscribe((val) => { console.log('Homemade val',val); }); setTimeout(() => { console.log('Cancelling homemadeStream'); subscription2.unsubscribe(); }, 1500); Calling dispose Produce values till someone calls unsubscribe var handle = setInterval(() => { observer.next( i++ ); }, 500); Define whats to happen on unsubscribe return function(){ console.log('Disposing timeout'); clearTimeout( handle ); }
  • 16. You will always create an observable from something
  • 17. 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)
  • 19. var stream = Rx.Observable.create((observer) => { var request = new XMLHttpRequest(); request.open( ‘GET’, ‘url’ ); request.onload =() =>{ if(request.status === 200) { } else { } } request.onerror = () => { } request.send(); }) stream.subscribe( ) observer.next( request.response ); (result) => { console.log( result ); } Get our data observer.complete(); () => { console.log(‘completed’); } No more data, close stream observer.error( new Error( request.statusText ) ) (err) => { console.log(err) }, observer.error( new Error(‘unknown error’) ); Error Error
  • 20. Hot vs Cold Observable
  • 21. Cold Observable recorded tv show Hot observable Live streaming eg World Cup Final
  • 22. Observables are cold by default, unless you make them hot var stream = Rx.Observable.interval(1000); stream.subscribe( (val) => { console.log('Subscriber 1', val);} ); stream.subscribe( (val) => { console.log('Subscriber 2', val); } ); var stream = Rx.Observable .interval(1000) .publish(); stream.subscribe((val) => { console.log('Subscriber 1', val); }); setTimeout(function() { stream.connect(); }, 2000); setTimeout(() => { stream.subscribe((val) => { console.log('Value', val); }); }, 4000); Subscriber 2 Values 0 1 2 3 4 Subscriber 1 Values 0 1 2 3 4 0 1 2 3 4 5 6 3 4 5 6
  • 23. You can create an observable from almost any async concept Operators however gives it its power Remember: But:
  • 24. Operators makes your code look like linq
  • 25. 120+ operators Rxjs 4 60+ Rxjs 5 Combination Conditional Multicasting Filtering Transformation Utility Categories in production
  • 26. Marble diagram how does that operator work
  • 27. Operator Most operators are covered at rxmarbles.com Stream 1 2 3 Other stream 4 5 Resulting stream 1 2 3 4 5
  • 28. Operator example var stream = Rx.Observable.of(1,2,3,4,5); stream stream.subscribe((data) => { console.log(‘data’); }) Operators : map() filter() 3 Emits 6 .map((val) => { return val + 1; }) changes the value .filter((val) => { return val % 3 === 0; }) filters out values
  • 29. Do var stream = Rx.Observable.of(1,2,3,4,5); var subscription = stream .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((val) => { console.log('Current val', val); }) Current val 1 Current val 2 Current val 3 Current val 4 Current val 5 Subscribe: 2 4
  • 30. debounce var debounceTime = Rx.Observable .fromEvent(button,'click') debounceTime.subscribe( function(){ console.log('mouse pressed'); }) waits x ms and returns latest emitted Ignores all generated mouse click events for 2 seconds.debounce(2000); Clicking save button 2secclick click click click click save()
  • 31. switchMap Switch map, complete something based on a condition breakCondition = Rx.Observable.fromEvent(document,'click'); breakCondition.switchMap((val) => { return Rx.Observable.interval(3000).mapTo(‘Do this'); }) breakCondition.subscribe((val) => { console.log('Switch map', val); }) Intended action is completed/restarted by ‘breakCondition’ etc.. Do this Do this Do this Do this Do this click click
  • 32. source.subscribe((data) => { console.log( data ); }) flatMap let source = Rx.DOM.getJSON( 'data2.json' ) return Rx.Observable.fromArray( data ).map((row) => { return row.props.name; }); return observable .flatMap((data) => { } ); We get an array response that we want to emit row by row We use flatMap instead of map because : We want to flatten our list to one stream
  • 33. flatMap explained when you create a list of observables flatMap flattens that list s Great when changing from one type of stream to another Without it you would have to listen to every single substream, w eve nt eve nt eve nt eve nt ajax ajax ajax ajax json json json json flatMap map
  • 34. Problem : Autocomplete Listen for keyboard presses Filter so we only do server trip after x number of chars are entered Do ajax call based on filtered input Cash responses, don’t do unnecessary calls to http server
  • 36. let input = $(‘#input’); input.bind(‘keyup’,() = >{ let val = input.val() if(val.length >= 3 ) { if( isCached( val ) ) { buildList( getFromCache(val) ); return; } doAjax( val ).then( (response) => { buildList( response.json() ) storeInCache( val, response.json() ) }); } }) fetch if x characters long return if cached do ajax Ok solution but NOT so fluent We need 3 methods to deal with cache
  • 38. Stream modeling key key key key key key FILTER AJAX CALL jso n jso n MAP key key key key key key key respons e respons e
  • 39. flatmapExample = Rx.Observable.fromEvent(input,'keyup') flatmapExample.subscribe( (result) =>{ console.log('Flatmap', result); buildList( result ) } ) more fluent Transform event to char.map((ev) => { return ev.target.value; }) Wait until we have 3 chars .filter(function(text){ return text.length >=3; }) Only perform search if this ‘search’ is unique.distinctUntilChanged() Excellent to use when coming from one stream to another .switchMap((val) => { return Rx.DOM.getJSON( 'data3.json' ); })
  • 43. retry let stream = Rx.Observable.interval(1000) .take(6); .map((n) => { if(n === 2) { throw 'ex'; } return n; }) Produce error .retry(2) Number of tries before hitting error callback stream.subscribe( (data) => console.log(data) (error) => console.log(error) 1 Emits 3 Makes x attempts before error cb is called
  • 44. retryWhen delay between attempts let stream = Rx.Observable.interval(1000) .take(6); delay, 200 ms.retryWhen((errors) => { return errors.delay(200); }) .map((n) => { if(n === 2) { throw 'ex'; } return n; }) produce an error when = 2 stream.subscribe( (data) => console.log(data) (error) => console.log(error) for those shaky connections
  • 45. What did we learn so far? We can cancel with .unsubsribe() We can retry easily A stream generates a continuous stream of values Operators manipulate either the values or the stream/s We can “patch” an erronous stream with a .catch() or Ignore a failing stream altogether with onErrorResumeNext
  • 47. What about schedulers and 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
  • 48. Schedulers testingvar 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); console.log('Should equal', result === 4); increment operator testScheduler.advanceBy(1000); testScheduler.advanceBy(1000); testScheduler.advanceBy(1000); assert console.log('Should equal', result === 2);
  • 50. .then vs .subscribe getData() .then( ) getData().subscribe( ) I will keep on streaming values (data) => console.log(data), (data) => console.log(data), (err) => console.log(err) (err) => console.log(err)
  • 51. user order orderItem Fetch user Then fetch order Lastly fetch order item
  • 52. Cascading calls Response: //getUser stream .subscribe((orderItem) => { console.log('OrderItem',orderItem.id); }) { id: 11, userId : 1 }.then(getOrderByUser) .switchMap((user) => { //getOrder return Rx.Observable.of({ id : 11, userId : user.id }).delay(3000) }) { id: 123, orderId : 11 }.then(getOrderItemByOrder) .switchMap((order) => { //getOrderItem return Rx.Observable.of({ id: 114, orderId: order.id }) }) { id: 1 }getUser() var stream = Rx.Observable.of({ id : 1 }); So we can see the first user observable being dropped when user 2 is emitted
  • 53. Short word on switchMap is to ensure we throw away the other calls when a new user is em We don’t want getUser getOrderByUser getOrderItemByOrder to complete if a new user is emitted 1 2 3 2 4 5 Not continued Replaces above stream
  • 55. Cascading call wait for the first .subscribe( (data) => { console.log( 'orders', data[0] ); console.log( 'messages', data[0] ); } ) var stream = Rx.Observable.of([{ id : 1 }, { id : 2 }]); getUser() We wait for user function getOrdersAndMessages(user){ return Promise.all([ getOrdersByUser( user.id ), getMessagesByUser( user.id ) ]) } .then(getOrdersAndMessages) stream.switchMap((user) => { return Rx.Observable.forkJoin( Rx.Observable.of([ { id: 1, userId : user.id } ]).delay(500), // orders Rx.Observable.of([ { id: 100, userId : user.id } ]).delay(1500) //messages ) }) Calls to orders and message can happen in parallel Orders,Messages arrive at the same time
  • 56. Last summary We can use schedulers to easily test our code Cascading calls can easily be setup switchMap over flatMap when doing ajax calls because we need it to abandon the stream if the first condition change
  • 57. Rxjs An elegant weapon for a more civilized age Remember..