Intro to
Observables
in JavaScript
slides.com/rebootjeff/observables
A top-down approach to learning observables
by @RebootJeff
outline [DELETE later]
- Observables are like data structures for events or: streams/collections of async events.
- can use for any async (DOM events, AJAX, websockets, animations, etc)
- `Observable.from()`
- composable
- lazy eval, cancellable (e.g., in React: componentWillUnmount -> unsub)
- structure
- separation of producer from consumers (via subscriptions)
- handlers (Observers have: next, error, complete)
- hot vs cold
- can use for any async (DOM events, AJAX, websockets, animations, etc)
- Use via RxJS
- Observables vs Promises
- Operators (conveniences)
- retry, debounce, buffer
- Possible use case: share 1 websocket connection to feed on multiple kinds of data (several widgets will open a max of 1 websocket)
- Related concepts
- Functional Programming / Reactive Programming, but NOT FRP??
- NOT going to cover how observables were inspired by 2 OOP patterns
- NOT related to `Object.observe()`
- History/References/links
- Rx started(?) by Microsoft; RxJS used/maintained heavily by Netflix
Overview
Basic Usage
var observable = Rx.Observable.create((observer) => {
var counter = 0;
var id = setInterval(() => {
if(counter < 9) {
observer.next(counter);
counter++;
} else {
teardown();
observer.complete();
}
}, 1000);
function teardown() {
clearInterval(id);
};
if(global.president === 'Donald') {
observer.error('Game over');
}
return teardown; // invoked when unsubscribing
});
// async logic begins on `.subscribe()`
observable.subscribe({
next: (val) => { console.log(val); },
error: (err) => { console.error(err); },
complete: () => { console.log('done!'); }
});
// we provided an observer
// if we want to cancel...
observable.unsubscribe();
// first, something familiar
promise.then(val => console.log(val))
.catch(err => console.error(err))
.finally(() => console.log('done!'));
Comparison
Error handling?
Promises
- Single fulfillment
- Run upon creation
- Can't stop
- Flatten themselves
- Simple
- Easy to learn
Observables
- Multiple values
- Lazy evaluation
- Can be cancelled
- Need flatMap
- Powerful
- Harder to learn
Operators
(slightly) Advanced Usage
What if we want type-ahead search results?
Requirements:
- Listen for user's typing events
- `input.keypress` --no such thing as `input.onChange` (contrived :p)
- Only respond once 2 chars entered
- Debounce the input
- Ask server a few times if HTTP call fails
- Render search results or error message
(slightly) Advanced Usage
(continued)
var searchInput = document.querySelector('#search');
Rx.Observable.fromEvent(searchInput, 'keypress')
.map(event => event.target.value)
.filter(value => value.length > 2)
.distinctUntilChanged()
.debounce(500)
.flatMap((value) => {
return Rx.DOM.request('/api/items?query='+value)
.retry(3);
})
.map(response => response.data)
.forEach(renderSearchResults)
.catch(err => renderError(err.message));
credit: Christian Alfoni
Caveats
- New paradigms:
- Reactive Programming
- FRP
- Many moving parts:
- observables
- observers
- subscriptions
- lifecycle of an observable
- "subjects"
- "schedulers"
There's a steep learning curve - link
- Academic teaching:
- bottom-up approach
- "push vs pull"
- "producers vs consumers"
- Funky terminology/API:
- "hot vs cold"
- "observable execution"
- Lots of tutorials for v4 API, but not v5
- Tough to find examples of RxJS + React
(but they're coming)
State of The Union Observable
- Pioneered by Microsoft? (in 2009?)
- Recently spotlighted by Netflix
(tech talks, video tutorials, blog posts, podcast talks) - Netflix guy on TC-39 pushing ES2016 observables spec
- There's also Bacon.js
- RxJS v5 - in beta; development led by Netflix for:
- improved performance
- friendlier debugging (call stacks)
- compliance w/ES2016 spec (proposal)
- greater modularity (import only what you need)
- marble diagrams in tests?
- RxJS embraced by Angular 2
Intro to Observables in JS
By rebootjeff
Intro to Observables in JS
1st draft completed 4/14/16
- 1,071