Skip to content

Instantly share code, notes, and snippets.

@amark
Created November 16, 2014 10:26
Show Gist options
  • Save amark/be8b72ab6159c263ea78 to your computer and use it in GitHub Desktop.
Save amark/be8b72ab6159c263ea78 to your computer and use it in GitHub Desktop.
parallel async JS micro library in 25LOC
var allDone = function(done){ // takes a callback that will be called as callback(errors, values) when all async parallel operations are finished.
var context = {task: {}, data: {}};
context.end = function(e,v){ return done(e,v), done = function(){} }; // this can always be called if you want to terminate early, like because an error.
context.add = function(fn, id){ // if the async operation you are doing replies with standard fn(err, value) then just pass in a string ID, else your own callback and ID.
context.task[id = (typeof fn == 'string')? fn : id] = false;
var next = function(err, val){
context.task[id] = true; // good, we're done with this one!
if(err){ (context.err = context.err || {})[id] = err } // record errors.
context.data[id] = val; // record the values.
for(var i in c.task){ if(c.task.hasOwnProperty(i)){ // loop over the async task checker
if(!c.task[i]){ // if any of them are still false
i = true;
break; // then break and...
}
} }
if(!(i === true)){ // only call done if i was never assigned to true, indicating there was no task left.
done(context.err, context.data);
}
}, c = context;
return (fn instanceof Function)? function(){ // if we have a callback, proxy it.
return fn.apply({task: c.task, data: c.data, end: c.end, done: next}, arguments);
} : next; // else just handle it ourselves.
}
return context;
};
// use:
[2, 3, 4, 9].forEach(function(num, i){
setTimeout(this.add(function(){ // async operation here, proxied via adding another task to allDone.
console.log('async doing', num);
this.done(null, num * num); // done done done... endlessly, until we are actually done.
}, i), 20); // the ID of i is the index of the array, and 20 is just a random number we set for the setTimeout, to get async behavior.
}, allDone(function(err, val){
console.log("all done!", err, val);
}));
@amark
Copy link
Author

amark commented Nov 16, 2014

If you like this, you'll probably like my newest open source project, GUN: https://github.com/amark/gun .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment