Skip to content

Instantly share code, notes, and snippets.

@markoutso
Last active August 24, 2016 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markoutso/bece8524bb2a842c9d13d189348d1e4c to your computer and use it in GitHub Desktop.
Save markoutso/bece8524bb2a842c9d13d189348d1e4c to your computer and use it in GitHub Desktop.
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