Introduction
to
RxJS
@namirsab [github | twitter]
Namir Sayed-Ahmad Baraza
namirsab@gmail.com
element.addEventListener('click', event => {
if (event.x >= 100 && event.y >= 100) {
const doubleCoordinates = {
x: event.x * 2,
y: event.y * 2
};
console.log('2x:', doubleCoordinates.x, ' 2y': doubleCoordinates.y);
}
});
When you see this...
const clicks = [ { x: 10, y: 20}, ... ];
clicks
.filter(click => click.x >= 100 && click.y >= 100)
.map(click => { x: click.x * 2, y: click.y * 2 })
.forEach(doubleCoordinates => {
console.log('2X': doubleCoordinates.x, ' 2Y':, doubleCoordinates.y);
});
Don't you find this...
...somehow similar?
// For each click event
element.addEventListener('click', event => {
// Filter it if does not pass a given predicate
if (event.x >= 100 && event.y >= 100) {
// Map it (Transform it)
const doubleCoordinates = {
x: event.x * 2,
y: event.y * 2
};
// Do something with it
console.log('2x:', doubleCoordinates.x, ' 2y': doubleCoordinates.y);
}
});
Check the semantics!
They are not that different!
What If...
Events
Arrays
?
Thats
what
RxJS does!
Hallo!
Ok, but...
What is RxJS?
...is a set of libraries to compose asynchronous and event-based programs using observable collections and Array#extras style composition in JavaScript
Using RxJS, developers represent asynchronous data streams with Observables, query asynchronous data streams using our many operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, RxJS = Observables + Operators + Schedulers.
RxJS
is Lodash
for Events
Why RxJS?
- Asynchronous programming in JS is just not comfortable ( callback hell )
doAsync(param, (result, error) => {
if (!error) {
doAnotherAync(result, (anotherResult, anotherError) => {
if (!anotherError) {
doSomething(anotherResult);
}
else {
console.err(anotherError);
}
});
}
else {
console.err(error);
}
});
Why RxJS?
- Promises make things cleaner
doAsync(param)
.then(result => doAnotherAsync(result))
.then(result => doSomething(result))
.catch(error => console.err(error))
- But...
- Promoses are not cancellable
- Promises are only good for single values
Why RxJS?
- RxJs "is" an evolution of promises
- It can handle multiple values (sequences or streams)
- The are cancellable
Rx Core Concepts
-
Observables / Observers
-
Subscriptions
-
Operators
Observables
Arrays
≈
-
Both represent a sequence of values
- Arrays are sequences in space
- Observables are sequences in time
- You can think about them as streams of events
Click events happenning in time
There are many ways to create observables
-
from events
-
from callback style functions
-
from promises
-
from arrays of values
-
from ranges
-
from scratch, to convert our asynchronous code to observables.
Examples
// From Event
const clicks = Rx.Observable.fromEvent(document, 'click');
// From Promise
const getJoke = Rx.Observable.fromPromise(
fetch('https://api.icndb.com/jokes/random')
);
// From Callback
const fromCallback = Rx.Observable.bindCallback(fnWithCallbackAtLast);
// From Array
const fromArray = Rx.Observable.from([1,2,3,4]);
// From Range
const range = Rx.Observable.range(1,5);
From Scratch
const simpleObservable = Rx.Observable.create(observer => {
let counter = 0;
const handler = setInterval(() => {
// Produce a random value
observer.next(Math.random());
counter++;
if (counter === 6) {
// Completes the sequence
observer.complete();
}
}, 500);
// Return an unsubscribe method so we can cancel
return () => {
clearInterval(handler);
}
});
Our first Observer
const subscription = simpleObservable
.subscribe(
randomNumber => console.log(randomNumber), // onNext,
err => console.log('error'),
() => console.log('Completed')
);
We subscribe to an Observable passing an Observer
An observer is just a set of 3 functions:
- next( value )
- error( error)
- complete()
Subscriptions
// When we call subscripe, we get a Subscription object
// which has an unsubscribe method
const subscription = simpleObservable
.subscribe(
randomNumber => console.log(randomNumber), // onNext,
err => console.log('error'),
() => console.log('Completed')
);
A subscription esentially has an unsubscribe function to release resources or cancel an Observable
subscription.unsubscribe();
Operators
Operators are just pure functions that create a new Observable based on the current one.
They are just like map, and filter in Arrays
Operators
Transformation Operators
Filtering Operators
- map
- scan (reduce)
- concatMap
- groupBy
- pluck
- window
Combination Operators
- merge
- zip
- concatAll
- combineAll
- filter
- debounce
- throttle
- first
- last
- take
An Observable looks like...
Demo Time!
Who is behind this?
Just a small company...
With some others, also small, using it
Pros/Cons
Pros
Cons
- Dealing with Asynchronous code is easier and more reliable
- The pattern is useful both for synchronous and asynchronous code
- Implies using functional programming which ensures code will be much more testable due to use of pure functions.
- Big learning curve
- Implies changing paradigm
- Number of operators is huge and understand what they do takes time
- Libraries don't return Observables, so you need to convert asynchronous code to Observables manually
- Library size is quite big, around 400 kb
Bibliography and Resources
Thank you for Listening!
and ask something, i'll try to answer! :D
RxJS
By Namir Sayed-Ahmad Baraza
RxJS
- 996