Skip to content

Instantly share code, notes, and snippets.

@sammoore
Created February 18, 2017 22:50
Show Gist options
  • Save sammoore/d21f81a9acb6a3a3382283fc4bff1289 to your computer and use it in GitHub Desktop.
Save sammoore/d21f81a9acb6a3a3382283fc4bff1289 to your computer and use it in GitHub Desktop.
Secret for da' fatha.
// ========================================
// == 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