Sunday, September 12, 2010

All Together Now

Last time, I talked about the Step.js library and how it helped make code look better when using the evented programming paradigmn. However, the first time I complained about the ugliness of code, the problem I highlighted was different. The problem was having multiple actions occur simultaneously and to continue once they are all done.

Let's take the example of loading a bunch of files, reading the contents and printing out the largest one. (it's a stupid example, I know, but the core of it is loading up a bunch of files before continuing. What's done with them is irrelevant. When I needed to do this I was caching a bunch of templates for a templating library.). Either because we are obsessive micro-optimizers or because the call is very slow (maybe the drive is on the network somewhere), we decide we want to load the files in parallel.

So why am I complaining? Firstly it's a lot of code. The problem is simple enough that I shouldn't have to write so much code. Secondly I had to maintain state in a scope outside the load function. I could trap it in a closure, but it's still annoying.

Rakesh Pai, a big fan of and contributor to tho Dojo project pointed out that Dojo's style of doing evented programming is in a way better suited to both this problem and the previous one than the default. Anything asynchronous in dojo always returns a Deferred object, which has a method called "andThen" . So you can do things like fs.writeFile(path, data).andThen(function(){fs.readFilepath)}) ... and so on. More importantly, a bunch of deferreds can be placed in a Deferred List and treated as one. Which means you can attach an event to be fired when all of them complete.

I think this too is a bit too wordy for me, but maybe it works in the entire dojo ecosystem as it is consistent with everything else. After all, Consistency is valuable for more than just databases and hashing schemes.

But let's see how step.js can help solve this problem.

Now that is so much nicer. No state maintenance, just pass in a function that executes multiple functions that take this.parallel as a callback and at the end we get all the results lumped together. The example is only marred by the stupid semantics of "this" in javascript (I call another function on array, so I'm forced to alias this. But without that magic, the library wouldn't work at all, so it's the price we pay.) and because for some retarded reason the arguments array is not a real array in javascript so I have to slice it in.

So there you have it, Step.js to write nicer code.

No comments:

Post a Comment