51
Discovering RxJS Angelo Simone Scotto angelo.scotto@computer .org May 03, 2016 Milan

Discovering RxJS - MilanoJS Meeting in May 2016

Embed Size (px)

Citation preview

Page 1: Discovering RxJS - MilanoJS Meeting in May 2016

Discovering RxJSAngelo Simone [email protected]

May 03, 2016Milan

Page 2: Discovering RxJS - MilanoJS Meeting in May 2016

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

Page 5: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 6: Discovering RxJS - MilanoJS Meeting in May 2016

Iterator Pattern

Page 7: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 8: Discovering RxJS - MilanoJS Meeting in May 2016

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> ?

Page 9: Discovering RxJS - MilanoJS Meeting in May 2016

Benjamin Franklin

«Tell me and I forget, teach me and I may remember, involve me and I learn»

Page 10: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 11: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>???

IDualEnumerator<T>

???

Page 12: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???

IDualEnumerator<T>

???

Page 13: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???(IDualEnumerator<T>)

IDualEnumerator<T>

???

Page 14: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???(IDualEnumerator<T>)

IDualEnumerator<T>

void ???

Page 15: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???(IDualEnumerator<T>)

IDualEnumerator<T>void ???( T )

Page 16: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???(IDualEnumerator<T>)

IDualEnumerator<T>void ???( bool, …, T )

Page 17: Discovering RxJS - MilanoJS Meeting in May 2016

DualityIEnumerable<T>

IEnumerator<T> GetEnumerator()

IEnumerator<T>

bool MoveNext() T Current()

IDualEnumerable<T>void ???(IDualEnumerator<T>)

IDualEnumerator<T>void ???( bool, Exception, T )

Page 18: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 19: Discovering RxJS - MilanoJS Meeting in May 2016

Observer

Page 20: Discovering RxJS - MilanoJS Meeting in May 2016

ObserverSubject

void Attach(Observer)void Detach(Observer)

Notify()

Observer

void Update()

Page 21: Discovering RxJS - MilanoJS Meeting in May 2016

ObserverSubject

void Attach(Observer)void Detach(Observer)

Notify()

Observer

void Update()

Page 22: Discovering RxJS - MilanoJS Meeting in May 2016

ObserverSubject<T>

void Attach(Observer<T>)void Detach(Observer<T>)

Notify(T)

Observer<T>

void Update(T)

Page 23: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 24: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 25: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 26: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 27: Discovering RxJS - MilanoJS Meeting in May 2016

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()

Page 28: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 29: Discovering RxJS - MilanoJS Meeting in May 2016

Promises are also Observables!

Single MultipleSync/Pull T IEnumerable<T>

Iterable of T

Async/PushTask<T>

Promise<T>Future<T>

IObservable<T>

Page 30: Discovering RxJS - MilanoJS Meeting in May 2016

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>

Page 31: Discovering RxJS - MilanoJS Meeting in May 2016

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>

Page 32: Discovering RxJS - MilanoJS Meeting in May 2016

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»

Page 33: Discovering RxJS - MilanoJS Meeting in May 2016

Code available at http://bit.ly/discoveringrxjs

DEMO

Page 34: Discovering RxJS - MilanoJS Meeting in May 2016

Rx is more than the Observable PatternLanguage neutral model based on 3 concepts:1. Observable Pattern.2. Composition operators & grammar.3. Schedulers and Time.

Page 35: Discovering RxJS - MilanoJS Meeting in May 2016

filter( ) : Filter elementsEmit only those items from an Observable

that pass a predicate test

0 431 2

0 4

Page 36: Discovering RxJS - MilanoJS Meeting in May 2016

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

Page 37: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 38: Discovering RxJS - MilanoJS Meeting in May 2016

DEMOCode available at http://bit.ly/discoveringrxjs

Page 39: Discovering RxJS - MilanoJS Meeting in May 2016

flatMap( ) : Map and then flattenTransform the items emitted by an

Observable into Observables, then flatten the emissions from those into a single

Observable

Page 40: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 41: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 42: Discovering RxJS - MilanoJS Meeting in May 2016

A simple example : Autocompletion

Page 43: Discovering RxJS - MilanoJS Meeting in May 2016

A simple example : Autocompletion

Events as Observables

Iterable as Observable Promise as Observable

Page 44: Discovering RxJS - MilanoJS Meeting in May 2016

DEMOCode available at http://bit.ly/discoveringrxjs

Page 45: Discovering RxJS - MilanoJS Meeting in May 2016

Rx is more than the Observable PatternLanguage neutral model based on 3 concepts:1. Observable Pattern.2. Composition operators & grammar.3. Schedulers and Time.

Page 46: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 47: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 48: Discovering RxJS - MilanoJS Meeting in May 2016

Schedulers in action!

Page 49: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 50: Discovering RxJS - MilanoJS Meeting in May 2016

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.

Page 51: Discovering RxJS - MilanoJS Meeting in May 2016

Thank you!Angelo Simone Scotto

[email protected]