SerialChain


chain
  .methodA('A') // => methodA() is asynchronous
  .methodB('B') // => methodB() is also asynchronous
  .methodA('more stuff')
  .done(function (err, results) {
    console.log(results); // => [ 'A', 'B', 'more stuff' ]
  });

Serial

  • JavaScript is asynchronous
var request = require('request');
    data = {};

request('https://google.com', function(err, res, body) {
  data = body;
});

console.log(data); // => {}

Serial

  • Callback hell is bad
var request = require('request');

request('https://google.com', function(err, res, body) {
  if (body.match('some string')) {
    request.('https://some.other.site', function(err, res, body) {
      if (body.match('blah blah')) {
        ... // turtles all the way down!
      }
    });
  }
});

Serial

  • The async module is cool
var async = require('async'),
    request = require('request');

async.series([
  function(done) {
    request('https://google.com', function(err, res, body) {
      done(err, body);
    });
  },
  function(done) {
    request('http://some.other.site', function(err, res, body) {
      done(err, body);
    });
  }
], function(err, results) {
  console.log(results); // => [ body, body ]
});

Chain

  • Chained code is pretty
var anArray = [ 'a', 'b', 'c' ];

var aNewArray = anArray
  .forEach(function(x) { console.log(x); }) // => a\nb\nc
  .filter(function(x) { return x == 'a' || x == 'c'; }) // removes 'b'
  .map(function(x) { return x+'!'; }); // adds a '!' to 'a' & 'c'

console.log(aNewArray); // => [ 'a!', 'c!' ];

Chain

  • return this; makes it shiny 
function Cache() {
  var _this = this;
  this._cache = {};
  this.addOne = function(kv) {
    var key = Object.keys(kv)[0];
    this._cache[key] = kv[key];
    return _this;
  };
  return this;
}

var cache = new Cache();
console.log(example._cache); // => {}
example
  .addOne({ keyOne: 'abc' })
  .addOne({ keyTwo: 'xyz' });
console.log(example._cache); // => { keyOne: 'abc', keyTwo: 'xyz' };
... but doesn't work well with asynchronous functions

Chain

  • Promises let you chain asynchronous functions
...
promise
  .then(function() {
    // do something async-y
  })
  .then(function() {
    // do something else async-y
  })
  .done(function(result) {
    // if there were no errors/rejections
  }, function(err) {
    // if there was an error =(
  });
... and that's cool, but kinda bulky

SerialChain

var SerialChain = require('serialchain');
 
var chain = new SerialChain({
  methodA: function (a, done) {
    setTimeout(function () {
      done(null, a);
    }, 100);
  }
});
 
chain.add('methodB', function (b, done) {
  setTimeout(function () {
    done(null, b);
  }, 500);
});
 
chain
  .methodA('A')
  .methodB('B')
  .methodA('more stuff')
  .done(function (err, results) {
    console.log(results); // => [ 'A', 'B', 'more stuff' ]
  });

References

SerialChain

By ben-bradley

SerialChain

A slide deck for PDXNode lightning talks!

  • 1,400