Async Loops In Node
I've been using Node for the past few weeks and I discovered a couple neat tricks about JavaScript that I never knew before.
Anonymous functions in JavaScript can have names.
Naming an anonymous function? Seems silly at first...
//no name provided repo.load_post(post_id, function(post) { // do something ... }); //with a name repo.load_post(post_id, function with_post(post) { // do something ... });
However, as it turns out, there are benefits to naming anonymous functions, especially when it comes to pinpointing an exception within a stack trace.
But this blog post is about writing async loops in Node -- So, how does naming functions help?
Function 'Names' Are Instances
I wrote an example a while back where I used the call
and apply
methods to pass additional loop information. You'd be able to reference this
to gather additional information about the loop you were currently in.
Except, in Node, this
seems to quickly lose a meaningful scope and you're forced to assign it to a variable that you can access from other nested closures.
However, since the function
object itself is accessable by name, you can use it to maintain a meaningful scope for your work.
function each(collection, action, finished) { //add loop information to the action action.index = -1; action.collection = collection; action.finished = finished || function() { }; //assign the loop control to the //anonymous method that was passed in action.next = function() { //quit now if the end has been reached if (++action.index >= collection.length) return action.finished(); //process this item var value = collection[action.index]; action(value); }; //start the loop action.next(); }
Now, at this point, we can control the loop using the anonymous function we passed in by referring to it by name.
//saves each person each( ['Hugo', 'Mary', 'Gwyn', 'Cassie', 'Ruby'], function loop(person) { //do an async method settings.save_profile( person, //then on the callback... function when_saved() { console.log(item + ' was saved...'); //... we can still access the loop loop.next(); }); });
This makes it easy to keep track of the scope of an anonymous function without needing to clutter up your code with extra variables. Now you can extend the functionality of anonymous functions with as much or as little information as you need and then access it by name. Very nice!
It is worth noting that I've heard that browser support for naming anonymous functions is rather limited in the browser world, so for the time being, it is probably best to keep this within your Node apps.
February 8, 2012
Async Loops In Node
Naming anonymous functions to make async loops easier to manage.