asynchronous programming & rxjs

March 2017, Denko Mancheski

workshop #3

AGENDA

- What is async and how does it work

- JS async callback hell

- Promises

- RxJS

BUT I ALREADY KNOW ASYNC...

 

 

THINKING ASYNCHRONOUSLY IS HARD...

BUT CHEER UP, EVENTUALLY YOU'LL GET IT!

EVENTUALLY YOU'LL GET IT...

WHAT IS ASYNC?

CODE THAT DOESN'T WAIT!

Will execute later

YOUR BRAIN IS AN ASYNCHRONOUS MACHINE

#devnexus #asyncprogramming #omgenius

OK, GOT IT

IS THERE ANYTHING MORE?

Pseudo-code

Example 

Quick reminders

JS is an event loop

JS is single-threaded

Async callbacks run on a basically empty call stack

Which makes debugging… interesting.

Async call stacks in DevTools

Chrome got async call stacks around version 35 (mid-2014).

“Traverses” async handovers: timers, XHR, promises, rAF, most observers, postMessage, FileSystem, IndexedDB…

JS Callback hell

Triangle of doom

What’s wrong?

Code doesn’t flow well

Mind / Code mapping is terrible.
(mostly because no returned value / entity)

Error management is a friggin’ mess.

Untrustworthy

Will it even run?

Will it run either error or success callbacks, not both?

Will it run only once?

No composability

Promises for the win

Pro’s and Con’s

Awesome:

Trustworthy: only one callback, only once, guaranteed. Plus, exceptions!

Composable: chainable, with injection and casting.

Not so awesome:

New abstractions

Slight performance penalty (improves, esp. with natives)

Code flow remains non-intuitive / very different from sync code.

Old-timers already

Been there a long time, under various forms and names.

Came into JS in 2007 through Dōjō.

Promises/A proposed in CommonJS in 2009 (Kris Zyp)

Promises/A+ in 2012 (Brian Cavalier, Domenic Denicola et at.)

More not so awesome things

Lack of Cancelation

Synhronization

Exceptions

...

 

Difficult and error prone

RxJS

FUNCTIONAL Reactive Programming

 

 

Making sense of ongoing events

EVERYTHING IS A STREAM

(click events, user inputs, data from server)

Observable creation

Observable usage

function searchWikipedia(term) {
  return $.ajaxAsObservable( /* … */ )
    .select(function(results) { return results.data; }); // Grab the data property
}

var input = $('#textInput');
var keyup = input.keyupAsObservable()                    // Event stream!
  .select(function() { return input.val(); })            // Grab the field value
  .where(function(text) { return text.length > 2; })     // Only proceed when long enough
  .throttle(500);                                        // Slow down, breathe…

var searcher = keyup
  .select(function(text) { return searchWikipedia(text); }) // Map on an XHR *result*!
  .switchLatest()                                           // Only keep latest response
  .where(function(data) { return data.length === 2; });     // Only keep useful results

searcher.subscribe(renderResults); // React to final stream by rendering UI

A powerful RxJS example

 

 

Functional programming

Avoid mutable state & side effects

Recursion

Higher-order functions

Function composition

Lazy evaluation

Pattern matching

 

 

Examples: map, filter, reduce, some..

We call these - Operators

RxJS =

Observables + Operators

Observable could be:

  • Array
  • Events (click, mousemove..)
  • Async I/O
  • Promises
  • Generators

A push based collection

 

Operators could be:

  • map
  • filter
  • concatAll
  • distinctUntilChanged
  • takeUntil
  • throttle
  • debounce
  • count
    and 200 more.

Why RxJS

  • Unifies both the world of Promises, callbacks as well as evented data such as DOM Input, Web Worker, Web Sockets..
  • Once we unify these concepts, this enables rich composition (superpower)

Hot vs Cold Observable

COLD is when your observable creates the producer

HOT is when your observable closes over the producer

const source = new Observable((observer) => {
  const socket = new WebSocket('ws://someurl');
  socket.addEventListener('message', (e) => observer.next(e));
  return () => socket.close();
});
const socket = new WebSocket('ws://someurl');
const source = new Observable((observer) => {
  socket.addEventListener('message', (e) => observer.next(e));
});

RxJS Subjects

  1. It’s an observable. It’s shaped like an observable, and has all the same operators.
  2. It’s an observer. It duck-types as an observer. When subscribed to as an observable, will emit any value you “next” into it as an observer.
  3. It multicasts. All observers passed to it via `subscribe()` are added to an internal observers list.
  4. When it’s done, it’s done. Subjects cannot be reused after they’re unsubscribed, completed or errored.
  5. It passes values through itself. To restate #2, really. If you `next` a value into it, it will come out of the observable side of itself.

Types of Subjects

Subject

both an observer and an observable. You can use a subject to subscribe all the observers, and then subscribe the subject to a backend data source

ReplaySubject

stores all the values that it has published. Therefore, when you subscribe to it, you automatically receive an entire history of values that it has published,

BehaviorSubject

is similar to ReplaySubject, except that it only stored the last value it published. BehaviourSubject also requires a default value upon initialization.

AsyncSubject

is similar to the Replay and Behavior subjects, however it will only store the last value, and only publish it when the sequence is completed

Useful Resources

  • https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
  • https://www.youtube.com/watch?v=8aGhZQkoFbQ
  • http://reactivex.io/documentation/operators.html
  • https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339#.ur1o5cfjm

Thanks for watching

If you have any question, do not hesitate:

denkomanceski@gmail.com

Made with Slides.com