Page 1 of 3

The jQuery function queue is probably one of the best ideas you will ever encounter, but it hardly gets a mention. The reason is that the problem it solves isn't an obvious one and neither is the way it is solved. It also doesn't help that function queues are usually introduced as a way to do animation - they are so much more.

Now Available as a Print Book:

You can buy it from:

USA and World Amazon.com

Canada Amazon.ca

UK Amazon.co.uk

France Amazon.fr

Germany Amazon.de

Spain Amazon.es

Italy Amazon.it

India Amazon.in

Japan Amazon.jp





The Core UI

Now Available as a Print Book:

You can buy it from:

USA and World Amazon.com

Canada Amazon.ca

UK Amazon.co.uk

France Amazon.fr

Germany Amazon.de

Spain Amazon.es

Italy Amazon.it

India Amazon.in

Japan Amazon.jp





Events, Async & AJAX

jQuery has some interesting ways of doing things and one that you cannot afford to miss is the function queue. It is a really great idea and once you understand it you will wonder how you ever did without it. It is the solution to a particular problem of calling asynchronous functions. It allows you to determine when one function has finished and the next can begin.

In many ways the function queue has been superseded by the more capable Promise, but for simplicity it is difficult to beat and well worth knowing about.

But to start at the beginning.

Basic Function Queues

Every element can have any number of function queues associated with it. Essentially a function queue is just an array used to store functions and is nothing particularly sophisticated. A function queue really does work in the way that you might imagine if you implemented the same facility yourself. Each element can have as many named function queues as you care to define, but there is also a default queue called fx which is used for animation. The default queue has slightly different behavior but more about this later.

To create a queue you can make use of the .queue or the $.queue function. The only difference is that the .queue function creates a queue for each of the elements in a result and the $.queue function has to have the element specified as the first parameter. In most cases you should use .queue.

You cannot create a queue without adding a function to it.

For example:

$({}).queue("myQueue",myFunction);

adds myFunction to a queue called myQueue and creates it if it doesn't already exist. In this example the queue is created on an empty object, which is perfectly valid and reasonable. If the function queue is to be applied to one or more elements, such as all divs, then you would use something like:

$("div").queue("myQueue",myFunction);

This would add a queue called myQueue to each of the divs in the document. The advantage of using an element is that this is set to the element when any function in the queue is executed, making it easy for the function to modify the element.

You can add multiple functions to a queue. For example:

var obj=$({}).queue("myQueue",myF1)

.queue("myQueue",myF2)

.queue("myQueue",myF3)

After this the queue has three functions stored in it.

A range of functions allow you to access and manipulate the queue:

.queue("queueName") returns the queue as an array .queue("queueName",newQueue) replaces the queue with the array of functions specified by newQueue .clearQueue("queueName") removes all the functions in the queue.

It is also worth knowing that once you have used .queue to retrieve the array of functions you can also use the usual Array methods - push, pop, unshift and shift - to manipulate the queue. The queue really is nothing more than an array.

For example:

var obj = $({}).queue("myQueue", myF1)

.queue("myQueue", myF2)

.queue("myQueue", myF3); console.log(obj.queue("myQueue").length);



function myF1() {

console.log("myF1");

}

function myF2() {

console.log("myF2");

}

function myF3() {

console.log("myF3");

}

You can see that we have queued three functions and the length property is used to confirm that the array really does have three elements.

Dequeue

So far there is nothing clever or exciting about the function queue. It is simply an array of functions. Notice that when the functions are added to the queue they just sit there doing nothing. For example, you don't see anything printed in the console log in the final example in the last section.

So how do you get the functions to do something?

The answer is the .dequeue function. When you call dequeue the function that is at the head of the queue is executed. Notice that the queue is a first in first out (FIFO) queue. What this means is the .dequeue wil execute the first function that you put in the queue.

For example with the three-function queue associated with obj in the previous example:

obj.dequeue("myQueue");

will result in myF1 being executed and you will see myF1 printed in the log. That is all that happens - dequeue runs a single function. If you want to execute the next function you need to use dequeue again:

obj.dequeue("myQueue");

then you will see myF2 in the log.

To see all three functions run you need:

obj.dequeue("myQueue")

.dequeue("myQueue")

.dequeue("myQueue");

This is easy enough to understand, but what possible advantage can it provide?

The key idea is that the dequeue function can be thought of as meaning "I'm finished - get on with the next function in the queue".

Once you realize this you can write the functions you are planning to queue so that they automatically dequeue any other functions remaining. That is:

function myF1() {

console.log("myF1");

$(this).dequeue("myQueue");

}

function myF2() {

console.log("myF2");

$(this).dequeue("myQueue");

}

function myF3() {

console.log("myF3");

$(this).dequeue("myQueue");

}

Notice that when each of the functions is executed this is the raw element or object that the queue is defined on. To use dequeue we have to wrap the object as a jQuery object. With these new functions the entire queue can be executed by a single

obj.dequeue("myQueue");

myF1 then executes myF2 by virtue of its dequeue function and myF2 runs myF3 by virtue of its dequeue command. Of course myF3's dequeue function doesn't do anything because the queue is empty at this point.

Again the mechanism is simple enough to understand but this is a complex way to just run three functions one after another. However when it comes to asynchronous functions it isn't always so easy to make sure they do run one after another.



