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

  • Unrelated to `Object.observe()`
  • Used for handling async actions:
    AJAX, websockets, DOM events, animations, AMQP(?)
  • They're basically streams/collections of events - link
    • Marble diagrams! - link
  • Most popular library is RxJS (Reactive Extensions)

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

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