Dusty
Dusty

Reputation: 173

jQuery - variable interval

Here's my current code:

$(document).ready( function() {

// set variables
var delay = 3000;

setInterval( function() {

    // perform AJAX call
    var req = $.ajax({
        url: "view/jquery/jq.refresh.php",
        dataType: "json"
    });

    // process data from json
    req.done( function(data) {
        $("#now_playing").html(data.song);
        $("#queue_list").html(data.queue);

        delay = data.time;
    });        

}, delay);
});

...and it's not working as planned.

The idea was to retrieve a variable delay (length of a song) from a database with AJAX. And put that delay (length of the song) into setInterval, this way the script would loop at variable intervals depending on the length of the song that is playing, hopefully reducing server/database load.

I'm sure that the correct value for the delay is retrieved from the database as adding console.log(date.time); shows me the length of the song.

One theory I have why my code won't work is that setInterval reads its ms value before actually processing the code within, so it's always set to 3000. Another theory is that delay = data.time doesn't change delay value because it's a global variable set at the start of the script.

So what options do I have to achieve a variable interval without crashing/freezing the browser?

Upvotes: 0

Views: 462

Answers (3)

Rory McCrossan
Rory McCrossan

Reputation: 337560

The delay of a call to setInterval() is only read once - when the interval is declared. Your attempt at changing the delay variable after instantiation will have no effect.

The alternative method is to chain setTimeout() calls, as you can then change the delay of the next timeout. Try this:

function createTimeout(delay) {
    setTimeout(function() {   
        $.ajax({
            url: "view/jquery/jq.refresh.php",
            dataType: "json"
        }).done(function(data) {
            $("#now_playing").html(data.song);
            $("#queue_list").html(data.queue);
            createTimeout(data.time);
        });            
    }, delay);
}

createTimeout(3000);

Upvotes: 0

Satpal
Satpal

Reputation: 133403

Since interval is set when initial call to setInterval made. modifying the value of delay will have no effect.

You should use setTimeout in this scenario.

$(document).ready(function() {
    // set variables
    var delay = 3000;

    //Define a function
    function getData() {

        // perform AJAX call
        var req = $.ajax({
            url: "view/jquery/jq.refresh.php",
            dataType: "json"
        });

        // process data from json
        req.done(function(data) {
            $("#now_playing").html(data.song);
            $("#queue_list").html(data.queue);

            delay = data.time;
            //Schedule the subsequent execution 
            setTimeout(getData, data.time);
        });
    }

    //Schedule to execute after 3 seconds on page load
    setTimeout(getData, delay);
});

Upvotes: 1

user229044
user229044

Reputation: 239311

setInterval reads its ms value before actually processing the code within, so it's always set to 3000

Yes. You only call setInterval once, and it's while the delay is set to 3000. Changing the value of delay after that point will have no affect on the already scheduled interval.

If you want a variable interval, you cannot use setInterval. Use setTimeout, and have each callback enqueue its subsequent callback.

function pollNext() {
    // perform AJAX call
    var req = $.ajax({
        url: "view/jquery/jq.refresh.php",
        dataType: "json"
    });

    // process data from json
    req.done( function(data) {
        $("#now_playing").html(data.song);
        $("#queue_list").html(data.queue);

       setTimeout(pollNext, data.time);
    });     

}

pollNext(); // Prime the initial invocation

Upvotes: 0

Related Questions