function Async() { return { bind: bind, run: run, sequence: sequence, wait: wait, wrap: wrap }; function bind(m, f) { return function(g) { m(function(x) { f(x)(g); }); } } function run() { var m; if(arguments.length == 1) { m = arguments[0]; } else { m = sequence.apply(null, arguments); } m(function() {}); } function sequence() { var steps = arguments; var i = 0; return function(f) { var step = function() { if(i < steps.length) { steps[i++](step); } else { f(); } } step(); }; } function wait(delay) { return function(f) { setTimeout(f, delay); }; } function wrap(x) { return function(f) { f(x); }; } }