Skip to content

Instantly share code, notes, and snippets.

@matthewmueller
Created March 11, 2012 23:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewmueller/2018660 to your computer and use it in GitHub Desktop.
Save matthewmueller/2018660 to your computer and use it in GitHub Desktop.
Javascript: step(fns...) - Tiny, flexible step function for running async functions in series
/*
Step - tiny, but flexible step library
Usage:
var first = function(next) {
...
return next(null, name, date);
}
var second = function(err, name, date, next) {
...
return next(null, person);
}
var last = function(err, person) {
...
}
step(first, second, last);
*/
var step = exports.step = function() {
var slice = Array.prototype.slice,
stack = slice.call(arguments).reverse(),
self = this;
function next(err) {
// Jump to last func if error occurs
if(err) return stack[0].call(self, err);
// Otherwise gather arguments and add next func to end
var args = slice.call(arguments);
if(stack.length > 1) args.push(next);
// Call the next function on the stack with given args
stack.pop().apply(self, args);
}
// Kick us off
stack.pop().call(self, next);
};
@matthewmueller
Copy link
Author

Improvement:

var series = step(initialArgs);
series(fn1, fn2, fn3, cb);

@matthewmueller
Copy link
Author

var step = exports.step = function() {
  var slice = Array.prototype.slice,
      args = slice.call(arguments),
      initial = function(next) { next.apply(self, args); },
      self  = this;

  return function() {
    var stack = slice.call(arguments).reverse();
    stack.push(initial);

    function next(err) {
      // Jump to last func if error occurs
      if(err instanceof Error) return stack[0].call(self, err);

      // Otherwise gather arguments and add next func to end
      var args = slice.call(arguments);

      if(stack.length > 1) args.push(next);
      else args.unshift(null);

      // Call the next function on the stack with given args
      stack.pop().apply(self, args);
    }

    // Kick us off
    stack.pop().call(self, next);
  };
};


var one = function(a, one, next) {
  console.log('a', a);
  console.log('one', one);
  setTimeout(function() {
    next(one);
  }, 1000);
};

var two = function(one, next) {
  console.log(one);
  setTimeout(function() {
    next(one);
  }, 1000);
};

step('a', 1)(one, two, function(err, blah) {
  console.log(err);
  console.log(blah);
});

step('b', 2)(one, two, function(err, blah) {
  console.log(err);
  console.log(blah);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment