Last active
October 12, 2015 13:18
-
-
Save Couto/4032670 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* __series | |
* Given an array of functions, it will call every function, | |
* once at a time, sequentially. | |
* Every function will have a trigger function as its last argument, | |
* that should be called when the function is done. | |
* If arguments are given to this trigger function, those will be passed | |
* to the next function. | |
* | |
* @example | |
* this.__series([ | |
* function doSomething(next) { | |
* //when it's done | |
* next(argument1, arguments2) | |
* }, | |
* function doSomethingElse(arg1, arg2, next) { | |
* // do something with the arguments, | |
* // and when it's done: | |
* next(); | |
* }, | |
* function doAnotherThing(next) { | |
* // because we didn't give arguments to this function | |
* // only the 'next' is available | |
* // when done. | |
* next(); | |
* } | |
* ]); | |
* | |
* | |
* @param {Array} fns Array of functions | |
*/ | |
var series = function (fns) { | |
(function next() { | |
var args = Array.prototype.slice.call(arguments); | |
fns.length && fns.shift().apply(this, args.concat(next)); | |
}()); | |
}; | |
/** | |
* __parallel | |
* | |
* Given an array of functions, it will call every function, | |
* in parallel. | |
* Every function will have a trigger function as its last argument, | |
* that should be called when the function is done. | |
* If arguments are given to this trigger function, those will be passed | |
* to the callback function. | |
* The callback function will have as many arguments as those you passed to the | |
* next function, by order. | |
* | |
* @example | |
* this.__parallel([ | |
* function doSomething(next) { | |
* //when it's done | |
* next(argument1, arguments2) | |
* }, | |
* function doSomethingElse(arg1, arg2, next) { | |
* // do something with the arguments, | |
* // and when it's done: | |
* next(); | |
* }, | |
* { | |
* fn: function doAnotherThing(next) { | |
* // because we didn't give arguments to this function | |
* // only the 'next' is available | |
* // when done. | |
* next(arguments4); | |
* }, | |
* cb: function (cancel, args4) { | |
* // Call this function only when doAnotherThing has ended | |
* // It's possible to cancel all future callbacks by calling | |
* // the 'cancel' function | |
* } | |
* } | |
* ], function (args1, args2, args4) { | |
* // All tasks were done. | |
* // and we get the argument1 and argument2 from the first | |
* // function and args4 from the third function. | |
* }); | |
* | |
* @method | |
* @private | |
* @param {Array} fns Array of functions | |
* @param {Function} callback Function to run when every function is complete | |
*/ | |
__parallel : function (tasks, callback) { | |
var counter = 0, | |
results = {}, | |
// Flag to know if it should run callbacks | |
enabled = true, | |
// Setter to disable callbacks | |
cancel = function () { enabled = false; }, | |
// function that will be given to each task, so that each task can | |
// notify when it's ready. | |
next = function (id) { | |
// Collect the given arguments given by the task | |
var args = Array.prototype.slice.call(arguments, 1); | |
// Save them in a final object | |
results[id.idx] = (args.length) ? args : undefined; | |
// Increment counter. | |
counter += 1; | |
// If the current task has an individual callback, call it, | |
// passing the arguments given by the task to the next function | |
// and the cancel function to give the option to disable future callbacks | |
if (id.cb && enabled) { id.cb.apply(this, [cancel].concat(args)); } | |
// If the counter reached the total number of tasks, call the | |
// 'done' function to parse the arguments for the final callback | |
if (counter === tasks.length && enabled) { done(); } | |
}, | |
// function that will parse all the arguments from the tasks, and | |
// it will call the callback arguments function given. | |
done = function () { | |
var finalArgs = []; | |
// Sort the arguments to be in the same order that the tasks | |
// given, and merge them into a single array | |
Object.keys(results).sort().forEach(function (val) { | |
finalArgs = finalArgs.concat(results[val]); | |
}); | |
// If a callback function was given, call it, passing the | |
// arguments | |
if (callback) { callback.apply(this, finalArgs); } | |
}; | |
tasks.forEach(function (task, index) { | |
// for each task in the array, check if has a property 'fn' | |
// if has, run that property, otherwise the task should be | |
// a function. | |
// curry an object giving the current index of the task and | |
// the individual callback if exists | |
(task.fn || task)(next.bind(this, { idx: index, cb: task.cb })); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment