Skip to content

Instantly share code, notes, and snippets.

@justinobney
Last active December 22, 2016 15:11
Show Gist options
  • Save justinobney/84eef91156ca6808daf4 to your computer and use it in GitHub Desktop.
Save justinobney/84eef91156ca6808daf4 to your computer and use it in GitHub Desktop.
const compose = (...fns) => (x) => fns.reduce( (v, f) => v.then ? v.then(f) : f(v), x)
function compose(...fns) {
var left = fns.shift();
return fns.length ? wrap(compose.apply(null, fns), left) : left;
function wrap(inner, outer) {
return function wrapped(...args) {
var innerResult = inner.apply(null, args);
return innerResult.then ? innerResult.then(outer) : outer(innerResult);
}
}
}
function compose() {
var functions = [].slice.call(arguments);
var composed = functions.pop();
if (functions.length == 0)
return composed;
var current;
while (current = functions.pop()) {
composed = wrap(composed, current);
}
return composed;
function wrap(inner, outer) {
return function() {
var args = [].slice.call(arguments);
var innerResult = inner.apply(null, args);
return innerResult.then ? innerResult.then(outer) : outer(innerResult);
}
}
}
describe('compose', function() {
it('can compose 2 functions', function() {
var lowerback = compose(lower, reverse);
expect(lowerback('BAR')).toBe('rab');
});
it('can compose functions with same input params', function() {
var lower_back_double = compose(lower, reverse, repeat);
expect(lower_back_double('BAR')).toBe('rraabb');
});
it('can compose functions with different input params', function() {
// order matters in this ecample
var lower_back_double = compose(lower, join, split, reverse, repeat);
expect(lower_back_double('BAR')).toBe('rraabb');
});
it('should handle flowing a promise', function(done) {
var asyncTest = compose(lower, reverseAsync);
asyncTest('BAR').then(function(result){
expect(result).toBe('rab');
done();
})
});
it('should handle flowing multiple promises', function(done) {
var asyncTest = compose(reverseAsync, lower, reverseAsync);
asyncTest('BAR').then(function(result){
expect(result).toBe('bar');
done();
})
});
});
function lower(str) { return str.toLowerCase(); }
function split(str) { return str.split(''); }
function join(strArray){ return strArray.join(''); }
function reverse(str) { return join(split(str).reverse()); }
function reverseAsync(str){ return Promise.resolve(reverse(str)); }
function repeat(str) {
return str.split('').map(function(letter) {
return letter + letter
}).join('');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment