Maya
Maya

Reputation: 1412

Delay JavaScript's function execution

I have a JQuery's .each loop that calls a function with a parameter per iteration, is there a way to delay this function call? I have tried setTimeout as in the following but this does not work as the function gets executed immediately.

$.each(myArray, function (j, dataitem)
{
     setTimeout(function () { showDetails(dataitem) }, 300);
});

function showDetails(dataitem)
{
...
}

Array size is roughly 20, What I'm trying to do is to distribute function calls over a certain time frame instead of immediately, any idea how to achieve this? I'm prepared to rewrite and restructure how functions get called to get this done, any help would be appreciated.

Upvotes: 8

Views: 6245

Answers (4)

Russ Cam
Russ Cam

Reputation: 125538

Take a look at jQuery.queue([ queueName ], callback( next )). This allows you to queue functions up to be called and is what jQuery's animation effects use internally.

It sounds like you would like to implement a queue, although it is not entirely clear you intentions for doing so.

EDIT: re-reading your question, I think other answers better match what you are after, however I thought that I would show you an example of how to achieve delayed function execution with a custom queue.

An example of how you could use a queue.

var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
    output = $('#output');

// set the queue up
$.each(myArray, function (j, dataitem) {
    output.queue('queue', function(next) {
        var that = this;
        showDetails(dataitem);  
        window.setTimeout(next,300);
    });
});

// start the queue running.
output.dequeue('queue');

function showDetails(dataitem) {
    output.append('<div>' + dataitem + '</div>');
}

Upvotes: 2

Shadow Wizzard
Shadow Wizzard

Reputation: 66398

You execute them all after 300 milliseconds. Instead, try something like this:

window.setTimeout(function () { showDetails(dataitem) }, (j + 1) * 300);

Edit: instead of creating 20 timers at once I think it's better to do it one by one. Function should be:

function showDetails(index)
{
   if (index >= myArray.length)
      return false;
   var dataItem = myArray[index];
   //code here......
   //code here......
   //code here......
   windows.setTimeout(function() { showDetails(index + 1); }, 300);
}

And first call can be:

$(document).ready(function() {
{
   showDetails(0);
});

This assume myArray is plain global array, and will handle one item and only then call the next item with delay.

Upvotes: 2

paztulio
paztulio

Reputation: 351

Just don't use $.each, but something like:

var data = [1, 2, 3, 4, 5];

function showDetails(values, delay) {
  console.log(values.shift()); //show the value
  if (values.length) {
    setTimeout(function() {showDetails(values, delay); }, delay); //schedule next elem
  }
}

showDetails(data.slice(0), 300); //dont forget the slice, call-by-reference

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039438

You could use the index of the array to calculate the interval dynamically:

$.each(myArray, function (j, dataitem) {
    window.setTimeout(function () { 
        showDetails(dataitem) 
    }, (j + 1) * 300);
});

Upvotes: 10

Related Questions