Cody G. Henshaw

Hacking the WWW

Shorthand Function Queues With JavaScript

This is a short post explaining the line that blew my mind from John Resig’s Secrets of the JavaScript Ninja. It turns out that it’s a cool shorthand way of iterating over and calling multiple (anonymous) functions from a queue. The following is the function in question.

queue.js mark:3,3
1
2
3
4
5
6
7
8
function runTest() {
  if (!paused && queue.length) {
    queue.shift()();
    if (!paused) {
      resume();
    }
  }
}

Let’s go ahead and break it out of the original function so that we can see what’s actually happening (this block comes from a big test suite, so that’s not helpful in this concise example). So, this is what we will be looking at:

1
queue.shift()()

Before we get into the queue part though, let’s take a gander at the shift() function.

The shift method removes the element at the zeroeth index and shifts the values at consecutive indexes down, then returns the removed value.

1
2
3
4
5
// create an array
var arrToShift = [1, 2, 3, 4, 5]
// shift returns the value it removes, so let's log that
console.log(arrToShift.shift()) // 1
console.log(arrToShift) // [ 2, 3, 4, 5 ]

Not so useful yet? Ok… how about if we replace the array of integers with an array of functions?

1
2
3
4
5
6
var queue = [ function(){ return 'foo' },
            function(){ return 'bar' },
            function(){ return 'bat' }
          ]

console.log(queue.shift()) // [Function]

So our shift() did exactly what it did in the first example. It removed and returned the value at queue[0], which in this case, was a function. How do we run a function in javascript? By appending () to the function, of course! So, now check this out…

1
2
console.log(queue.shift()()) // foo
// woohoo! we returned that first function and ran it

You should now be able to see how we could use this as I mentioned earlier. Let’s run ALL of our functions in the queue.

1
2
3
4
5
6
7
sLen = queue.length; // starting queue length
for(var i = 0; i < sLen; i++) {
  console.log(queue.shift()())
}
// foo
// bar
// bat

That’s kind of long though, and this was about shorthand… SO, we can use shift() to our advantage here as well. Since the 0th element is REMOVED from the array, we should be able to just check if there is something at the 0th index. If so, we can keep going. This is the shorter version that I came up with.

1
2
3
4
5
while(queue[0]) { console.log(queue.shift()()); }
// while anything is at the 0th index, continue running
// foo
// bar
// bat

Pretty cool, right? We could also accomplish a queue-like system with map(), something like queue.map(function(x){ console.log(x()) })… That’s a different story though. Hopefully you took something away from this post… Feel free to catch up with me (or point out errors) on twitter @CodyHenshaw.