using
RX.js 5
Nadav Sinai @ Misterbit
mail: ns@nadavsinai.com
web: nadavsinai.com
twitter: @nadavsinai
github: github.com/nadavsinai
JS is sync
let x = getValue();
for (let x of someIterable){
....
}
/// pull based
// we don't know when to pull
Web is Async
DomEvents
WebSockets
Ajax
ServiceWorker
WebWorker
GeoLocation
Fetch
Push values - async
let cb = (err,value) => {
}
doSomethingAsync(cb);
/// or better
doSomethingReturningPromise.then(value =>{
}).catch(errHandler)
But What about multiple value?
Single | Multiple | |
---|---|---|
Pull | Function | Iterator |
Push | Promise | Observable |
Observables are async primitive, just like promises
let myPromise = new Promise(function(resolve){
resolve(42);
})
myPromise.then(value =>console.log(value));
let myObservable$ = Rx.Observable.create(function(observer){
observer.next(42);
})
myObservable$.subscribe(value => console.log(value));
Like promises they contain the error logic and allow for one place of catching it.
let myPromise = new Promise(function(resolve,reject){
resolve(42);
})
myPromise.then((value) => console.log(value),(error) => console.debug(error));
//or
myPromise
.then((value) => console.log(value))
.catch((error) => console.debug(error));
let myObservable$ = Rx.Observable.create(function(observer){
observer.next(42);
})
myObservable$.subscribe(value => console.log(value));
They can return multiple values
They can complete
They can be sync/async
They are lazy
They can be multicast/unicast
let myObservable$ = Rx.Observable.create(function(observer){
observer.next(42);
observer.next(53);
})
myObservable$.subscribe(value => console.log(value));
let infinite = Rx.Observable.interval(1000);
infinite.subscribe(console.log)
let myObservable$ = Rx.Observable.create(function(observer){
observer.next(42);
observer.next(53);
observer.complete();
})
myObservable$.subscribe({next:(v)=>console.log(v),complete:()=>console.info('complete'));
let finite = Rx.Observable.interval(1000).take(5);
finite.subscribe((v)=>console.log(v),(e)=>console.error(e),(c)=>console.info(c));
export function getState(store:Store<any>):any {
let state;
store.take(1).subscribe(s => state = s);
return state;
}
var observable = Rx.Observable.create(function (observer) {
console.log('In creation function');
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
});
console.log('after observable setup');
// nothing happens...
.share() === .publish().refCount()
Observables are simple functions taking an observer and returning cancellation function.
Rx.Observable.create(function(observer){
// can setup the data source here
//then can call next/error/completed on the observer here
return function(){
//can do any teardown logic here
}
});
the observer itself is just an interface :
interface Observer<T> {
isUnsubscribed?: boolean;
next: (value: T) => void;
error: (err: any) => void;
complete: () => void;
}
Rx.js adds the following logic bits to every observable we create :
If you pass an Observer doesn’t have all of the methods implemented, that’s okay.
`next` can not be called after a `complete` or an `error`
Nothing can be called after source is unsubscribed.
Calls to `complete` and `error` need to call unsubscription logic.
If any handler function throws an exception, unsubscription logic is called
Rx.js adds the following logic bits to every observable we create :
If you pass an Observer doesn’t have all of the methods implemented, that’s okay.
`next` can not be called after a `complete` or an `error`
Nothing can be called after source is unsubscribed.
Calls to `complete` and `error` need to call unsubscription logic.
If any handler function throws an exception, unsubscription logic is called
Rx.js has many helper function to create observables
Observable.from
Observable.of
Obserable.fromEvent
...has many ways to connect observables
Observable.merge
Observable.mergeMap
Observable.withLastestFrom
Observable.switchMap
Or the timing of running the subcription:
Observable.prototype.debounce()
Observable.prototype.throttle()
Observable.prototype.takeUntil()
There 105 operators in the current rx.js beta.
You must add them to the build in order to use them
(import 'rxjs/add/operator/map')
Q & A