Upload
angelo-simone-scotto
View
105
Download
1
Embed Size (px)
Citation preview
Discovering RxJSAngelo Simone [email protected]
May 03, 2016Milan
EFSA Hackathon • Free contest open to any European citizen.
• Develop innovative mobile apps using EFSA open data.
• €20,000 as first prize.
• Key dates• June 30, 2016: prototype
submission.• «End of September»
2016: winners announcement.
• Make us proud
More info at http://bit.ly/efsa_hackathon
What is Rx ?
MSDN Rx introduction
What is Rx ?
MSDN Rx introduction
Back in 1994…• Design Patterns was
published.• Written by Gamma,
Helm, Johnson, Vlissides (Gang of Four)
• Contains 23 «recipes» to solve abstract problems with Object-Oriented approach.
Iterator Pattern
Iterator Pattern C#Aggregate<T>
Iterator<T> CreateIterator()
Iterator<T> void First() void Next() bool IsDone() T CurrentItem()
IEnumerable<T>IEnumerator<T> GetEnumerator()
IEnumerator<T> void Reset() bool MoveNext() T Current()
ConcurrencyIterator is represents a «pull-based» collection, what about a «push-based» collection?
Single MultipleSync/Pull T IEnumerable<T>
Iterable of T
Async/PushTask<T>
Promise<T>Future<T> ?
Benjamin Franklin
«Tell me and I forget, teach me and I may remember, involve me and I learn»
Duality• Hint 1: Subject of pull based collection is
consumer of collection («give me the next element»).
• Hint 2: Subject of push based collection is producer of collection («take this next element»).
• Hint 3: Input / Output are inverted between producer and consumer (producer see next element as output, consumer as input).
• A push-based collection is therefore the dual of a pull based collection.
• To switch consumer with producer we just need to switch input with output.
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>???
IDualEnumerator<T>
???
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???
IDualEnumerator<T>
???
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T>
???
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T>
void ???
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T>void ???( T )
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T>void ???( bool, …, T )
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T>void ???( bool, Exception, T )
DualityIEnumerable<T>
IEnumerator<T> GetEnumerator()
IEnumerator<T>
bool MoveNext() T Current()
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T> void OnNext(T) void OnError(Exception) void OnComplete()
Observer
ObserverSubject
void Attach(Observer)void Detach(Observer)
Notify()
Observer
void Update()
ObserverSubject
void Attach(Observer)void Detach(Observer)
Notify()
Observer
void Update()
ObserverSubject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Notify(T)
Observer<T>
void Update(T)
IDualEnumerable = Observer 2.0Subject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Observer<T>
void Update(T)
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T> void OnNext(T) void OnError(Exception) void OnComplete()
IDualEnumerable = Observer 2.0Subject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Observer<T>
void Update(T)
IDualEnumerable<T>void ???(IDualEnumerator<T>)
IDualEnumerator<T> void OnNext(T) void OnError(Exception) void OnComplete()
IDualEnumerable = ObservableSubject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Observer<T>
void Update(T)
IObservable<T>void Subscribe(IObserver<T>)
IObserver<T> void OnNext(T) void OnError(Exception) void OnComplete()
IDualEnumerable = ObservableSubject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Observer<T>
void Update(T)
IObservable<T>void Subscribe(IObserver<T>)
void Unsubscribe(IObserver<T>)
IObserver<T> void OnNext(T) void OnError(Exception) void OnComplete()
IDualEnumerable = ObservableSubject<T>
void Attach(Observer<T>)void Detach(Observer<T>)
Observer<T>
void Update(T)
IObservable<T>IDisposable Subscribe(IObserver<T>)
IObserver<T> void OnNext(T) void OnError(Exception) void OnComplete()
IDualEnumerable = ObservableIObservable<T>
IDisposable Subscribe(IObserver<T>)
IObserver<T> void OnNext(T) void OnError(Exception) void OnComplete()
• Unsubscribe was not necessary on iterator, added as Subscribe return value.
• Event Streams does not complete neither fail.
• Collection can, hopefully, complete and can, unfortunately, raise exceptions.
Promises are also Observables!
Single MultipleSync/Pull T IEnumerable<T>
Iterable of T
Async/PushTask<T>
Promise<T>Future<T>
IObservable<T>
Promises are also Observables!
Single MultipleSync/Pull T IEnumerable<T>
Iterable of T
Async/PushTask<T>
Promise<T>Future<T>
IObservable<T>
• A single element of T can be seen as a specific IEnumerable<T>
Promises are also Observables!
Single MultipleSync/Pull T IEnumerable<T>
Iterable of T
Async/PushTask<T>
Promise<T>Future<T>
IObservable<T>
• A single element of T can be seen as a specific IEnumerable<T>
• A single promise of T can be seen as a specific IObservable<T>
Antoine de Saint-Exupéry
«Perfection is achieved, not when there is nothing more to add, but when there is
nothing left to take away»
Rx is more than the Observable PatternLanguage neutral model based on 3 concepts:1. Observable Pattern.2. Composition operators & grammar.3. Schedulers and Time.
filter( ) : Filter elementsEmit only those items from an Observable
that pass a predicate test
0 431 2
0 4
map( ) : Transform elementsTransform the items emitted by an
Observable by applying a function to each item
0 1 2
0 1
43
2 3 4
takeUntil( ) : CompleteDiscard any items emitted by an Observable after a second Observable emits an item or
terminates 0 1 2 43
0 1 2Hint: Don’t unsubscribe from Events, complete them when another fires.
DEMOCode available at http://bit.ly/discoveringrxjs
flatMap( ) : Map and then flattenTransform the items emitted by an
Observable into Observables, then flatten the emissions from those into a single
Observable
flatMap( ) : Map and then flattenTransform the items emitted by an
Observable into Observables, then flatten the emissions from those into a single
Observable
Notice: if mapped observables are slow, events may interleaveNotice: if interleaving is not acceptable, use concatMap instead.
flatMapLatest( ) : Map and then flattenTransform the items emitted by an
Observable into Observables, then flatten the emissions from those into a single
Observable
Notice: flatMapLatest exists that is like flatMap but keeps listening on last Observable only.
A simple example : Autocompletion
A simple example : Autocompletion
Events as Observables
Iterable as Observable Promise as Observable
DEMOCode available at http://bit.ly/discoveringrxjs
Rx is more than the Observable PatternLanguage neutral model based on 3 concepts:1. Observable Pattern.2. Composition operators & grammar.3. Schedulers and Time.
SchedulersRx schedulers provide an abstraction that allows work to be scheduled to run, possibly in the future, it controls when a subscription starts and when notifications are published.One can:• Subscribe using a particular scheduler
(using subscribeOn)• Observe using a particular scheduler
(using observeOn)Plus, every operator that needs to introduce concurrency in the system (mainly generators) is parametrized by an optional scheduler.
Since JavaScript is essentially single-threaded, schedulers options are quite limited, and the default scheduler is usually the right choice.
Available Schedulers in RxJSScheduler Descriptionimmediate Gets a scheduler that schedules
work immediately on the current thread.
currentThread Gets a scheduler that schedules work as soon as possible on the current thread.
default Gets a scheduler that schedules work via a timed callback based upon platform.
TestScheduler Virtual time scheduler used for testing applications and libraries built using Reactive Extensions.
HistoricalScheduler
Provides a virtual time scheduler that uses a Date for absolute time and time spans for relative time.
Schedulers in action!
ConclusionsUse Rx and Observable to help you to:• Avoid callback hell, tons of callbacks and
global variables in your async code, relay instead on just one, carefully crafted, observable.
• Enhance promises in supporting multi-value and cancellation.
• Forget removeEventListener and unsubscription/cancellation code, just use takeUntil on your observables.
To continue your journey…• ReactiveX: Homepage of RX project.• LearnRX: Online tutorial, published
initially by Netflix as training for its developers.
• RxJSKoans: GitHub repository full of small exercises of increasing difficulty using RxJS.
• Rx Workshop: A set of videos teaching you Rx.NET directly from Rx team members.
• IntroToRx: Free book about previous version of Rx.NET (v1.x). Still a great introduction as concept are still valid and API is not changed so much.