Theory of RXJS Slides
Theory of RXJS Slides
class ApiService {
getData(): Promise<Data>;
getData(): Observable<Data>;
@synalx
1 2 3
@synalx
In the beginning: Callbacks
@synalx
In the beginning: Callbacks
@synalx
In the beginning: Callbacks
@synalx
Callback Hell
@synalx
Promise
@synalx
Promises
Disconnect the action from what comes next
@synalx
Beyond Promises
Promises have their own problems
@synalx
Observables
Are similar to Promises:
Async primitive
Lazy
@synalx
Eager vs. Lazy
@synalx
Mental Model
Sync Async
Eager
Lazy
@synalx
Mental Model
Sync Async
Eager
Scalar
Lazy
@synalx
Mental Model
Sync Async
Eager
Scalar
Lazy
() => Scalar
@synalx
Mental Model
Sync Async
Eager
Scalar Promise
Lazy
() => Scalar
@synalx
Mental Model
Sync Async
Eager
Scalar Promise
Lazy
@synalx
Lazy + Async
// Later on...
getData().then(freshData => console.log(freshData));
@synalx
Services as a container for async functions
class ApiService {
getData(): Promise<Data> {
return fetch(‘/api/data’).then(r => r.json());
}
@synalx
Mental Model
Sync Async
Eager
Scalar Promise
Lazy
@synalx
Mental Model
Sync Async
Eager
Scalar Promise
() => Promise
Lazy
() => Scalar
Observable
@synalx
Observables as async functions
@synalx
Basic example
@synalx
Basic example
@synalx
Long running example
@synalx
Back to ApiService
class ApiService {
getData(): Promise<Data>;
getData(): Observable<Data>;
@synalx
Back to ApiService
class ApiService {
getData(): Promise<Data>;
data$: Observable<Data>;
@synalx
1 2 3
Operators
@synalx
Operators
Observable → Observable
100+ operators!
@synalx
Array-like operators
map
(Value → Value)
filter
@synalx
map
@synalx
Projection
Sometimes we want to asynchonously transform values
Value → Observable
@synalx
Projections
@synalx
Higher-order Observable
Observable<Observable<Data>>
@synalx
Higher order Observable
Observable<Observable<Data>>
etc.
@synalx
Projection operators
Transform Observable<Observable<T>> to Observable<T>
@synalx
Projection operators
Transform Observable<Observable<T>> to Observable<T>
@synalx
map → concat
@synalx
map → concat
@synalx
When to use each operator?
@synalx
Result selectors
@synalx
Result selectors
@synalx
Combination operators
combineLatest
withLatestFrom
@synalx
combineLatest
@synalx
withLatestFrom
@synalx
1 2 3
@synalx
Anti-pattern: nested subscriptions
subscribe() should happen as close to the UI as possible
@synalx
Anti-pattern: nested subscriptions
http.get(‘/first’).subscribe(first => {
this.first = first;
http.get(first.url).subscribe(second => {
this.second = second;
});
});
@synalx
Instead, use projection operators
http.get(‘/first’).pipe(
concatMap(
first => http.get(first.url),
(first, second) => ({first, second})
)
).subscribe(({first, second}) => {
this.first = first;
this.second = second;
});
@synalx
Pattern: subscription management
You should always unsubscribe
@synalx
First, create an onDestroy$ stream
ngOnDestroy(): void {
this.onDestroy$.next();
}
}
@synalx
As the last step in every sequence, use takeUntil
class ApiService {
data: Data;
Instead:
Stateless services
NGRX
@synalx
Pattern: custom operators
Operator is a function which transforms a given
Observable → Observable
@synalx
Pattern: custom operators
@synalx
1 2 3
@synalx
Thank you!
Follow me on twitter: @synalx
@synalx