Thursday, August 5, 2010

A little JavaScript™ Invention

One deficiency in JavaScript™ is that it has no sleep command. Instead, it has a setTimeout function, which works differently: you tell it what you want to run, and how long you want it to be before it starts, and that acts like a little time bomb in the background while your program continues on. It doesn't pause. So if you want it to actually pause, you need to pass the entire rest of your program in.

That sounds crazy, and it kind of is. But JavaScript™ (I'm writing it that way because it really is a trademarked name) is for web apps, where you don't really run a whole program. What you're usually writing is callbacks for widgets. It's a callback-oriented language.

So today, I had the need to put a pause in a series of requests I was making, so that they wouldn't all happen at once. How to do that as I'm looping through the array? Tail-recursion, of course— that's how you loop in a functional language. I came up with a function that works like the forEach method, only it has a specified pause before invoking the callback:

          // Like forEach, but with a delay
function delayForEach (queue, callback, delay) {
var qIdx = 0;
// recursive block
(function () {
if (qIdx < queue.length) {
callback(queue[qIdx], qIdx);
++qIdx;
setTimeout(arguments.callee, delay);
}
})();
}

It's just a little thing, but I thought it was nicely elegant. It should be noted that this call will all run "in the background": if you call delayForEach on some array, your program will continue on, and the looping will be done as if it were running independently. Still, could be useful for somebody.

Upon reflecting a bit, it seems to me that it might be more appealing to use setInterval instead.

         function delayForEach (queue, callback, delay) {
var qIdx = 0,
interval = setInterval(function () {
if (qIdx < queue.length) {
callback(queue[qIdx], qIdx);
++qIdx;
}
else {
clearInterval(interval);
}
})();
}

1 comment:

Roy said...

Every time I edit the post, it screws up my code formatting. That last example is (as yet) untested, and I think it's missing a closing brace.