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!
And we definitely agree on functions- they can be passed as arguments, close over variables, defer the execution of some code until they are
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
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.
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
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"
The Monolog app will be rewritten in Rx-Helper style
Live at: http://www.deanius.com/monolog.html
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