Last active
August 24, 2016 19:58
-
-
Save markoutso/bece8524bb2a842c9d13d189348d1e4c to your computer and use it in GitHub Desktop.
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
function Async(fn, args=[]) { | |
let stack = [(handler) => fn.apply(undefined, args.concat([handler]))]; | |
let error = (e) => { throw new Error(`An error occured - ${e.message}`); } | |
function asyncCombine(fn, nfn, nargs) { | |
return handler => fn((...args) => { | |
let res = getOrError(args); | |
return nfn.apply(undefined, nargs.concat([res, handler])); | |
}); | |
} | |
function mapCombine(fn, nfn) { | |
return handler => fn((...args) => { | |
let res = getOrError(args); | |
return handler(nfn(res)) | |
}); | |
} | |
function combine(fn, [nfn, nargs]) { | |
return nargs === undefined ? mapCombine(fn, nfn) : asyncCombine(fn, nfn, nargs); | |
} | |
function catchError(fn) { | |
try { | |
return fn(); | |
} catch (e) { | |
error(e); | |
} | |
} | |
function getOrError(args) { | |
if (args.length == 2 && args[0] !== undefined) throw args[0]; | |
return args.length == 1 ? args[0] : args[1]; | |
} | |
return { | |
andThen(fn, args=[]) { | |
stack.push([fn, args]); | |
return this; | |
}, | |
map(fn) { | |
stack.push([fn]); | |
return this; | |
}, | |
onError(fn) { | |
error = fn; | |
return this; | |
}, | |
run(handler) { | |
let fn = stack.reduce(combine); | |
return catchError(() => fn(handler)); | |
}, | |
} | |
} | |
function block(ms) { | |
let previous = new Date().getTime(); | |
let passed = 0; | |
let total = 0; | |
let current; | |
while (total < ms) { | |
current = new Date().getTime(); | |
passed = current - previous; | |
previous = current; | |
total += passed; | |
} | |
} | |
function pseudoAsync(fn, delay) { | |
return (...params) => { | |
block(delay); | |
let l = params.length; | |
let handler = params[l - 1]; | |
return handler(fn.apply(undefined, params.slice(0, l - 1))); | |
} | |
} | |
let fn1 = pseudoAsync((a,b) => a + b, 1000); | |
let fn2 = pseudoAsync(a => a + 1, 1000); | |
let fn3 = pseudoAsync(r => { console.log(r); return r}, 100); | |
Async(fn1, [1, 2]).map(x => x + 1).andThen(fn2).andThen(fn3).run(console.log); | |
Async(fn1, [1, 2]).map(x => x + 1).andThen(function() {throw new Error("lala")}).andThen(fn3).run(console.log); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment