Will
Will

Reputation: 119

How can I use setTimeout within a loop with different lengths of timeout?

var playlist = [    
        ['Message 1','1000'],
        ['Message 2','6000'],
        ['Message 3','1000'],
        ['Message 4','8000']
    ];
    for (i = 0; i < playlist.length; i++) {
       setTimeout((function(x) { return function() { 
          $("content").empty().append("<p>" + playlist[x][0] + " timeout: " + playlist[x][1] + "</p>");
       }; })(i), playlist[i][1]*i)
    }   

I'm trying to create a timer where the length of each setTimeout interval varies depending on a variable stored in an array. For example I am expecting 'Message 1' to be displayed for 1 second, followed by 'Message 2' displayed for 6 seconds, and so on through the array.

However, the messages appear in an unexpected order, and the periods which they are on screen doesn't appear to relate to the corresponding delay I've specified in the array.

Ideally I'd also like the process to loop back to the start of the array once it gets to the end.

Any help would be much appreciated!

Upvotes: 0

Views: 569

Answers (1)

soulprovidr
soulprovidr

Reputation: 754

Edit: with the looping condition:

var timer = null;
var index = -1;
var playlist = [
    { message: "Message 1", duration: 1000 },
    { message: "Message 2", duration: 6000 },
    { message: "Message 3", duration: 1000 },
    { message: "Message 4", duration: 8000 }
];

function displayNextMessage() {

    // If the next message exists...
    if (playlist[++index]) {

        // ...do something with the message here...
        console.log(playlist[index].message);

        // ...and queue the next message.
        timer = setTimeout(function () {
            displayNextMessage();
        }, playlist[index].duration);
    }

    // Otherwise, loop back to the beginning.
    else {
        index = -1;
        displayNextMessage();
    }
}

displayNextMessage();

Then, to stop the loop, you can call:

clearTimeout(timer);

Upvotes: 1

Related Questions