Created
June 6, 2013 16:24
-
-
Save pdswan/5722843 to your computer and use it in GitHub Desktop.
semi-functional js experimentation forcing sequentially execution
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
var assert = require('assert') | |
function _if(predicate) { | |
return { | |
then: function(thenFn) { | |
return { | |
else: function(elseFn) { | |
predicate.map(function(val) { | |
if (val) thenFn() | |
else elseFn() | |
}) | |
} | |
} | |
} | |
} | |
} | |
function Point(val) { | |
return { | |
map: function(fn) { fn(val) } | |
} | |
} | |
function Fn(fn) { | |
return { | |
map: function(gn) { gn(fn()) } | |
} | |
} | |
var TRUE = Point(true) | |
var FALSE = Point(false) | |
var result | |
function thenFn() { result = 'then' } | |
function elseFn() { result = 'else' } | |
_if(TRUE).then(thenFn).else(elseFn) | |
assert.equal('then', result) | |
_if(FALSE).then(thenFn).else(elseFn) | |
assert.equal('else', result) | |
function sequentially(callbackFns, actualCallback) { | |
var results = [ ] | |
var noMoreCallbacks = Fn(function() { return callbackFns.length === 0; }) | |
var finishOrNext = function() { | |
_if(noMoreCallbacks) | |
.then(finish) | |
.else(iterate) | |
} | |
finishOrNext() | |
function iterate() { | |
callbackFns.shift()(internalCb) | |
} | |
function internalCb(err, result) { | |
if (err) { | |
finish(err) | |
} else { | |
results.push(result) | |
finishOrNext() | |
} | |
} | |
function finish(err) { | |
actualCallback(err, results) | |
} | |
} | |
function sleep(duration, cb) { | |
setTimeout(cb, duration) | |
} | |
function fn1(cb) { | |
sleep(1000, function() { | |
cb(null, "fn1") | |
}) | |
} | |
function fn2(cb) { | |
sleep(500, function() { | |
cb(null, "fn2") | |
}) | |
} | |
function fn3(cb) { | |
sleep(250, function() { | |
cb(null, "fn3") | |
}) | |
} | |
function err(cb) { | |
cb("This is an error") | |
} | |
sequentially([fn1, fn2, fn3], function(err, results) { | |
assert.ok(typeof(err) === 'undefined') | |
assert.deepEqual(['fn1', 'fn2', 'fn3'], results) | |
}) | |
sequentially([fn1, fn2, err, fn3], function(err, results) { | |
assert.equal("This is an error", err) | |
assert.deepEqual(['fn1', 'fn2'], results) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment