jQuery 3 - Function Queues
Written by Ian Elliot   
Monday, 30 January 2017
Article Index
jQuery 3 - Function Queues
The Async Problem
Chained Auto Queuing

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.

 Available as a Book:

smallcoverjQuery

buy from Amazon

  1. Understanding jQuery
  2. Basic jQuery CSS Selectors
       Extract: The DOM
  3. More Selectors
       Extract: Basic Selectors
  4. The JQuery Object
  5. Filters 
  6. DOM Traversal Filters 
  7. Modifying DOM Objects
       Extract: Modifying The DOM 
  8. Creating Objects & Modifying The DOM Hierarchy
  9. Working With Data
       Extract: Data ***NEW!!!
  10. Forms 
  11. Function Queues
  12. Animation 
  13. jQuery UI
  14. jQuery UI Custom Control
  15. Easy Plugins 
  16. Testing With QUnit
  17. Epilog A Bonus Function

Also Available:

jquery2cover

buy from Amazon

 

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.


justjquery

 



Last Updated ( Monday, 30 January 2017 )