Created
February 18, 2017 22:50
-
-
Save sammoore/d21f81a9acb6a3a3382283fc4bff1289 to your computer and use it in GitHub Desktop.
Secret for da' fatha.
This file contains 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
// ======================================== | |
// == Utilities | |
// ======================================== | |
// assuming you're using old browsers... this | |
// should work for most kinds of array-like objects. | |
var arrayFrom = function arrayFrom(iterable) { | |
return Array.prototype.slice.call(iterable); | |
}; | |
// you'll probably want to use this so you don't | |
// have to wrap functions yourself. | |
// | |
// Usage (if console.log supports multiple params): | |
// var sayHelloTo = partial(console.log, "hello,"); | |
// sayHelloTo("world!"); | |
// | |
var partial = function partial(fn) { | |
var partialArgs = arrayFrom(arguments).slice(1); | |
return function () { | |
var that = this || undefined; | |
var remainingArgs = arrayFrom(arguments); | |
var args = partialArgs.concat(remainingArgs); | |
return fn.apply(that, args) | |
}; | |
} | |
// ======================================== | |
// == series | |
// ======================================== | |
// Expects `tasks` to be an array of `Function`s | |
// that accept one argument, a callback. | |
var series = function (tasks, callback) { | |
var resultsList = []; | |
resultsList.length = tasks.length; | |
var done = function (idx, result) { | |
resultsList[idx] = result; | |
// `Object.keys` excludes missing values | |
var count = Object.keys(resultsList).length; | |
if (count == resultsList.length) { | |
callback(resultsList); | |
} | |
}; | |
tasks.forEach(function (task, idx) { | |
var taskDone = partial(done, idx); | |
task(function () { | |
// the `results` for each task is an array | |
// of the arguments passed to its callback | |
var results = arrayFrom(arguments); | |
taskDone(results); | |
}); | |
}); | |
}; | |
// ======================================== | |
// == Usage | |
// ======================================== | |
// will never produce an error, but shares callback-style (err, result) | |
var async1 = function async1(val, callback) { | |
setTimeout(function () { | |
callback(null, val); | |
}, 2000); | |
}; | |
// produces an error if `str` isn't a primitive string. | |
var asyncString = function async2(str, callback) { | |
setTimeout(function () { | |
if (typeof str != 'string') { | |
var msg = "expected 'str' to be type string, found: "; | |
msg += typeof str; | |
return callback(new TypeError(msg)); | |
} | |
callback(null, val); | |
}, 1000); | |
}; | |
var tasks = [ | |
partial(async1, "Hello, "), | |
partial(asyncString, "world!") | |
]; | |
// A use-case for the above `async*` functions. | |
series(tasks, function (resultsList) { | |
// results is an array of arrays, since we cannot | |
// assume only 1 value will ever be passed to a | |
// callback function used with `series`... | |
// | |
// repetitive to keep things simple: | |
var errors = resultsList.map(function (results) { | |
return results[0]; | |
}); | |
var values = resultsList.map(function (results) { | |
return results[1]; | |
}); | |
// Get any error or `false`. `Array#some` isn't | |
// widely supported AFAIK, so I used `#reduce`: | |
var anyError = errors.reduce(function (result, each) { | |
return !!result ? result : each; | |
}, false); | |
// Normal stuff here after unwrapping results arrays: | |
if (anyError) { | |
var message = anyError.message || anyError; | |
return console.log('FAIL: ', message); | |
} | |
var output = values.join(''); | |
console.log('pass: ', output); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment