UnitJS/async.js

132 lines
2 KiB
JavaScript
Raw Normal View History

function Async() {
return {
apply: apply,
bind: bind,
fail: fail,
http: http,
map: map,
parallel: parallel,
run: run,
sequence: sequence,
wait: wait,
wrap: wrap
};
function apply(f, x) {
return function(g) {
g(f(x));
};
}
function bind() {
var m, steps, i;
if(arguments.length < 1) {
return wrap();
}
m = arguments[0];
steps = arguments;
i = 1;
return function(f) {
var step = function(x) {
if(i < steps.length) {
steps[i++](x)(step);
} else {
return f(x);
}
}
m(step);
};
}
function fail(message) {
return function(f) {
console.log(message);
}
}
function map(mapper) {
return function(x) {
return function(f) {
f(mapper(x));
};
};
}
function parallel() {
var threads = arguments;
var pending = threads.length;
var results = [];
var returned = [];
return function(f) {
var useResult = function(i) {
return function(x) {
if(!returned[i]) {
results[i] = x;
returned[i] = true;
pending--;
if(pending < 1) {
f(results);
}
}
};
};
for(var i = 0; i < threads.length; i++) {
threads[i](useResult(i));
}
};
}
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(x) {
if(i < steps.length) {
steps[i++](step);
} else {
f(x);
}
}
step();
};
}
function wait(delay) {
return function(f) {
setTimeout(f, delay);
};
}
function wrap(x) {
return function(f) {
f(x);
};
}
function http(query) {
return function(f) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {
f(this);
});
xhr.open(query.method, query.url);
if(query.method == 'POST') {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
xhr.send(query.body);
};
}
}