Skip to content

Instantly share code, notes, and snippets.

@deanius deanius/monolog-intro.md
Last active Mar 13, 2019

Embed
What would you like to do?

Rx-Helper - Web Development based on Events and Primitives; Not Frameworks.

If you were not around web development when Backbone came on the scene in 2010, let me tell you what a breath of fresh air it was! After 4 years of JQuery proliferation (2006), which ended the wars of Prototype (2005), MooTools and such, the promise of a New Order that the 2010-generation of web frameworks brought (including my beloved Knockout.js) was breathing hope into web developer's hearts. No longer would server-code like Rails (2005) need to control your front-end code!

But it was the dawn of new complexity as well. And soon build tools like Browserify (2011) would become a must, and JS Fatigue was setting in. To deal with that, we'd eventually form encampments around technologies that came with their own toolchains such as MeteorJS (2007), Angular (2010), Ember (2011), ReactJS (2013), and GraphQL (2015). We needed these build solutions - so what else could we do! Soon, few people moved between multiple of these techs, because the desire to rebuild your whole build chain was just not there. And, separated by our build tools, our approaches to components really started to diverge. These days, we happily inhabit our little bubbles. It's like a modern day Tower of Babel - we're fragmented into different-speaking populations. (And I didn't even mention you Clojure (2007) or Elm (2012)!)

But, Surely We Agree on Something!

JavaScript! Just kidding. All JS dialects (and I call using a Framework a dialect, if not its own language) support Arrays, Objects, numbers and strings - basically everything that can be serialized into JSON is common to every dialect. These dataypes, called primitives, which we might call the building blocks, or elements of JS programs.

And we definitely agree on functions- they can be passed as arguments, close over variables, defer the execution of some code until they are call-ed.

Promises? Streams? Event Emitters?

There's another class of datatypes. Unlike the aforementioned things you might find in a JSON file, there are datatypes which accept your functions as arguments, and can call them later. These are collectively known as 'async' or 'reactive' datatypes. For example, a Promise, to which you pass a function into its then method. While many languages hardly deal in these datatypes at all (Ruby), they are de-rigueur (simply essential!) in JavaScript, where they happen whenever you pass in a callback function, either directly or via Promises.

Scenario:  App is an application with a dependency on 'Lib', a library.

            Imperative GET/UPDATE          
       App ----calls fn of ---> Lib
       App <-- data flows ---- Lib
       
             Reactive 'onClick'
       App ---- hands fn to --> Lib
       Lib ----calls fn of ---> App
       Lib ----passes data ---> App
       

The Promise of Promises

The main advantage Promises brought to the scene were that:

  • Consistency - There was a specification, the A+ Promises spec, which you were guaranteed a Promise adhered to.
  • Better Decoupling - No longer did the callee library ever need to hold a reference to a function from the caller.

Promises are now part of this common specification that all dialects can work with, since they were standardized in ES2015. But since working with async is so fundamental to JavaScript, many variants of async have emerged: Callbacks, Promises, Generators, Functional Reactive Programming (FRP), Communicating Sequential Processes (CSP), and Observables. One of them will be explored here as a cross-language concept that is just a small enough change compared to Promises, that they might become standard - Observables.

The Observable Successor to Promises

First I'll explain why Observables may supersede Promises, then I'll build an app with them so you can see for yourself their impact on code simplicity.

Currently Observables are:

  • A Stage 1 Draft Proposal at TC39
  • Not to be unseated by cancelable Promises - despite what you may have heard
  • Usable using RxJS or Zen Observable
  • Embedded in Angular and the Apollo GraphQL Library
  • Available in over 10 languages (not just JavaScript!)

Observables are useful for modeling:

  • Writing to a file in an async, or synchronous way
  • The calling of an HTTP endpoint
  • A file listener which notifies of changes within a directory
  • The listening for user clicks in a browser, and the providing of stream of those clicks
  • The incoming HTTP requests to a server, and a stream of all these requests
  • An animation loop which provides events each time it's done painting the previous frame

This is a broader set of use cases than Promises, due to :

  • Observables can handle multiple events (or behave in a 1-and-done Promise-like way)
  • Ability to be sync or async (Promises are only async)
  • Ability to be started lazily, and
  • Ability to be canceled after being started

Generally, Observables are a superset of Promise functionality. They can model what Promises can't and thus absorb complexity and provide a dependable contract to what would have to be implemented in custom glue code if you only used Promises as your abstraction.

#Popularity With every Angular and GraphQL developer in 2019 already using Observables, even if unbeknownst to them, there is already a larger base using them there was using Promises back in early 2010. So it's not too small a niche.

But regardless, I think their utility transcends frameworks, primarily in their ability, when used effectively, to make frameworks unnecessary except at the outer edges of a system. This is the desired Clean Architecture (2012) that can be rephrased as "Functional Core, Imperative Shell"

Case Study

The Monolog app will be rewritten in Rx-Helper style

Old Revisions

Live at: http://www.deanius.com/monolog.html

References

Writing

Kim Joar Bekkelund's JQuery-to-Backbone Tutorial

Jake Archibald on Promises

David Shariff on Promises aka Futures

The TC39 Observable Proposal

The Withdrawn TC39 Cancelable Promises Proposal

Uncle Bob on Clean Architecture

Libraries

Zen Observable

RxJS

Angular

Apollo GraphQL

MonologueJS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.