Skip to content

Instantly share code, notes, and snippets.

@epappas
Created July 11, 2014 13:05
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 epappas/c9bf1be47be6815d915c to your computer and use it in GitHub Desktop.
Save epappas/c9bf1be47be6815d915c to your computer and use it in GitHub Desktop.
Allochron; how async.parallel should be like.
'use strict';
module.exports = function allochron(funcs, onComplete, limit) {
funcs = typeof funcs === 'function' ? [funcs] : funcs;
limit = limit || 3;
var scope = this;
var length = Object.keys(funcs).length;
var shouldRun = {val: true};
var counter = {i: length};
var handler = __handler.bind(scope, onComplete, shouldRun, counter, {/* errors */}, [/* results */]);
limit = limit < length ? limit : length;
var wraps = [];
funcs.forEach(function(fn, index, funcs) {
wraps.push((function(fn, index, wraps, nextIndex) {
fn(handler.bind(scope, index, wraps[nextIndex]));
}).bind(scope, fn, index, wraps, index + limit));
});
for(var i = 0; i < limit; ++i) {
try {
wraps[i]();
}
catch(e) {
shouldRun.val = false;
onComplete([e], null);
}
}
function __handler(onComplete, shouldRun, counter, errors, results, index, next, err, result) {
if(err) errors[index] = err;
else results[index] = result;
if(shouldRun.val === true) {
if(--counter.i === 0) onComplete(Object.keys(errors).length > 0 ? errors : null, results.length > 0 ? results : null);
else if(next) next();
}
}
};
'use strict';
var allochron = require('./allochron');
var assert = require('assert');
allochron([
function(cb) {
console.log('Func 1 is Running', Date.now());
setTimeout(function() {
cb(null, [1,2,3]);
}, 1000);
},
function(cb) {
console.log('Func 2 is Running', Date.now());
setTimeout(function() {
cb(null, 123);
}, 1000);
},
function(cb) {
console.log('Func 3 is Running', Date.now());
setTimeout(function() {
setTimeout(function() {
cb(null, {a:123});
}, 300);
}, 1000);
},
function(cb) {
console.log('Func 4 is Running', Date.now());
setTimeout(function() {
setTimeout(function() {
cb(new Error('Test Here'), null);
}, 400);
}, 500);
},
function(cb) {
console.log('Func 5 is Running', Date.now());
setTimeout(function() {
setTimeout(function() {
cb(null, 'abcdefg');
}, 600);
}, 800);
},
function(cb) {
console.log('Func 6 is Running', Date.now());
setTimeout(function() {
setTimeout(function() {
cb(new Error('Test Here'), 123);
}, 1500);
}, 1000);
}
], function(errs, results) {
console.log('OnComplete: ', arguments);
assert(errs[0] === undefined);
assert(results[0].length === 3);
assert(errs[1] === undefined);
assert(results[1] === 123);
assert(errs[2] === undefined);
assert(results[2].a === 123);
assert(errs[3] instanceof Error);
assert(results[3] === undefined);
assert(errs[4] === undefined);
assert(results[4] === 'abcdefg');
assert(errs[5] instanceof Error);
assert(results[5] === undefined);
allochron([
function() {
abcde();
}
], function(errs, results) {
assert(errs[0] instanceof Error);
console.log('ReferenceError is checked:', errs);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment