Question

I'm working on a JavaScript driven site where I will have a lot of stuff that need's to be executed in a certain order. A lot of the stuff involves animations and AJAX-loading. Some pseudo code could look like this:

  1. Load JSON formated data
  2. Generate HTML-elements using the loaded JSON data and render them inside a div
  3. Make the elements inside the div scrollable using a jQuery UI slider
  4. Randomize a number between 1 and the total number of loaded elements
  5. Make the jQuery UI slider scroll (animate) to the element that represents the randomized number for a duration of 500 milliseconds
  6. Load more JSON formated data
  7. Replace other elements on the page
  8. And so on...

Each step in this is wrapped in a function - one function loads the JSON data, another generates the HTML-elements, a third initializes the jQuery UI slider and so on. Encapsulating the code in functions makes the code easier to read for me, but above all I want to be able to call the functions in different orders depending on what happens on the page and I want to be sure that one function has finished running before the next one is executed.

If there was just regular functions that didn't involve AJAX or jQuery animations I'd just execute the functions I want to execute, one after the other. The problem is that I need to wait for the animations and data retrieving functions to finish before moving on. To aid me both the animation and AJAX methods in jQuery allow me to send along a callback. But here's where I get lost.

What I want it to do is the following:

  1. Load JSON data. If the loading is successful, go on and...
  2. Generate HTML-elements
  3. Make the elements scrollble
  4. Randomize a number between 1 and the total number of loaded elements and pass it to...
  5. A function that makes the jQuery slider slide (animated) to the element. When the animation is finished...
  6. Load more JSON formated data. If the loading is successful, go on and...
  7. Replace other elements on the page

The ideal thing would be if I could set up this sequence/chain of events in one single place, for example inside an event handler. If I want to call the functions in a different order or not call all of them I would just set up a different sequence/chain. An example could be:

  1. Randomize a number between 1 and the total number of loaded elements and pass it to...
  2. A function that makes the jQuery slider slide (animated) to the element. When the animation is finished...

This means that I'd have to be in control over the callbacks in each step.

I hope you understand what I'm looking for. I want to control the entire execution sequence from a single function. This function would be "the conductor of the orchestra" and all the other functions would be the different instrument sections of the orchestra. This conductor functions need's ears so it can hear when the violinist is finished with her solo and can tell the horns to start playing. Excuse me for the corny allegory, but I hopes it makes it easier to understand what I want to do.

Thanks in advance! /Thomas

Was it helpful?

Solution 4

I found that what I was trying to achieve was slightly overkill for my purposes. So I decided to go with a different approach. I can send one or more boolean variables as a parameters to a function and use them to decide whether to execute a second function or not. Here's an example:

$("#justOneStep").click(function() {
   loadImage(false);
});

$("#twoStepsPlease").click(function() {
   loadImage(true);
});


function loadImage(boolDoMore) {
   // Do the stuff that loads an image
   ...

   if(boolDoMore) {
      nextFunction();
   }
}

function nextFunction() {
   // Do some more stuff
   ...
}

Not very fancy but easy to understand and control and sufficient for my needs at the moment.

/Thomas

OTHER TIPS

Would the jQuery .queue() function help you?

Could you store a sequencer variable that is an array (which you would be able to change) and then call a sequencer at the end of each function?

You could then pass a step code through each function and cross-reference that with the sequencer variable as to what the next step should be.

Pseudo Code:

var func['1'] = function(arg1,arg2,seq) {
  //code
  sequencer(seq);
}

var func['2'] = function(arg1,arg2,seq) {
  //code
  sequencer(seq);
}

var func['3'] = function(arg1,arg2,seq) {
  //code
  sequencer(seq);
}

var func['4'] = function(arg1,arg2,seq) {
  //code
  sequencer(seq);
}

function sequencer(seq) {
  seq = seq + 1;
  window.func[seq]
}

I tried executing this code:

var seq = 0;
var func = [];

func[1] = function(seq) {
    setTimeout(function() {
        console.log("Executing function 1");
        sequencer(seq);
    }, 2000);

}

func[2] = function(seq) {
    console.log("Executing function 2");
    sequencer(seq);
}

func[3] = function(seq) {
    console.log("Executing function 3");
}

function sequencer(seq) {
    seq = seq + 1;
    func[seq].call();
}

sequencer(seq);

But the result (in Firebug) is:

Executing function 1

func[seq] is undefined
[Break on this error] func[seq].call(); 

I think that the problem is caused by context, but I'm not sure. JavaScript is sensitive to the context in which a function is called.

/Thomas

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top