keys() is an Object method

For a little while I didn’t really *get* the difference between underscore and async in node.js.

Yesterday I wrote up some code to copy some data out of PostgreSQL and into CouchDB. At some point, I have a big object whose keys are the document IDs in my CouchDB database, and I needed to fire up request to update each document in turn. Because I’m lazy, I usually use _.keys(object) to get an object’s keys so my server-side and client-side javascript follow the same conventions. To apply a function to the object key value pairs, I would normally use _.each(object,function(value,key){...}), but in this case, where I want a little more control over how many simultaneous GETs then PUTs I fire off at CouchDB, underscore’s each is a little awkward to use.

In the past I’ve hacked up self-made limiters, but as I use async more I’ve been learning about useful ways to combine its functions. In this case, I made an async.whilst loop that splices out 30 or so ids, then uses async.forEach() to fire off request operations for each of these document ids. The request operations themselves are nested—I usually try to use pipe whenever I can (pipe the get into the put), but I haven’t yet tested what happens when you modify the document in between the get and the put.

In short, my current approach is that when I want simple iterators I use underscore, but if there is a whiff of blocking in the call, I will use async instead. As I follow this convention, it begins to get more and more useful. In underscore, the function just runs. If it is something like a request call that will return right away and go do something asynchronously, then I have to program my own solution to figuring out when that call is done. In contrast, async makes liberal use of callbacks. async.forEach() will also fire off lots of simultaneous request objects, but it passes its own callback function to each one of them, and I can trigger them all in the final callback in my request invocation. Very handy. And then async has a third optional argument that is a function to execute when all of the parallel forEach calls are done. Again, very handy, and much cleaner than hacking up my own solution.

Which brings me back to my title. Because I’m not using underscore in this case, I suddenly didn’t want to use _.keys(object) to get the list of keys. Naively I tried object.keys(), but that is an error. The proper semantics is Object.keys(object), and I learned something super basic at the same time that I am settling far more complicated usage patterns.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s