/** * Simple asynchronous tool for saving my life. */ /** * A wrapper function create a `Chain` instance at the same * time initializes the `queue` with a serial of arguments. */ module.exports = function() { var s = new Chain(); return s.__init.apply(s, arguments); } /** * Chain constructor. * @api pivate */ function Chain() { this.queue = []; this.onend = function(err) {}; this.pass = true; } /** * Trying to Initialize the `queue` with a serial of arguments. * * @api private */ Chain.prototype.__init = function() { this.queue = [].slice.call(arguments); return this; } /** * Add a `job` or an array of `jobs` into the Chain. * A `job` is defined by a function. * * @param {Function|Array} a function or an array of functions * @return {Chain} * @api public */ Chain.prototype.add = function() { var jobs = [].slice.call(arguments); jobs.forEach( (function(job) { this.queue.push.apply( this.queue, Array.isArray(job) ? job : [job] ); }).bind(this) ); return this; } /** * The iterator of the Chain. When it reaches end then call * call the callback function. * * @return {Chain} * @api public */ Chain.prototype.next = function() { if (!this.pass) return this; if (this.queue.length) { this.queue.shift().call(); } else { this.onend(); } return this; } /** * Terminate the chain. * * @return {Chain} * @api public */ Chain.prototype.stop = function() { this.pass = false; this.onend.apply(this, arguments); return this; } /** * Start iterating through the Chain and ends with the * given callback. * * @param {Function} end callback * @return {Chain} * @api public */ Chain.prototype.traverse = function(fn) { fn && fn.call && fn.apply && (this.onend = fn); this.next(); return this; }