Skip to content

Instantly share code, notes, and snippets.

@matthewmueller
Last active August 29, 2015 14:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewmueller/0c5db8b413e97d2658af to your computer and use it in GitHub Desktop.
Save matthewmueller/0c5db8b413e97d2658af to your computer and use it in GitHub Desktop.
Some quick notes on flow-based programming

Flow-based Programming is all about reacting to event sources. Event sources in the browser might be:

  • A DOM event
  • AJAX call
  • Onload initial data passing
  • Local DB fetch (local storage, indexdb)

In order to build larger systems, nodes need to be chainable and flows need to be composable. I think the best way to do this in Javascript may look something like this:

var rx = RX(event('click'))
  .use(class.add('highlight'));
  .use(batch(local('some key'), remote('POST http://endpoint.com'));
  
rx(document.querySelector('button'));

function local(key) {
  return function(el) {
    localstorage.set(key, { target: el.className, action: 'click' });
  }
}

function remote(url) {
  var curl = parse(url);
  return function(el, fn) {
    http[curl.method](curl.url, function(err, res) {
      if (err) return fn(err);
      return fn(null, res);
    });
  }
}

The following script listens for clicks on a button and reacts to them by saving the click locally and sending it to an API endpoint. batch does these operations in parallel.

You'll also notice with a click event, the flow is initialized but the flow doesn't continue until a click operation is performed on the button.

Any flow can be added to any other flow:

var a = rx()
  .use(...)
  .use(...)

var b = rx()
  .use(a)
  .use(...);

Here b uses the flow of a. What is passed into b, initializes the flow.

rx#use(fn) takes a function that can either by synchronous or asynchronous depending on if a fn is passed through. rx#use(fn) will wait at each step until the previous step finishes.


Pros:

  • Everything is reactive and is built with that mindset.
  • Everything is composible
  • Everything is functional and easily testable

Cons:

  • Nearly every existing library would need to be wrapped in order to fit within this paradigm. Take a look at all the components https://github.com/noflo has had to create.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment