JeremyW
JeremyW

Reputation: 743

setInterval with an Array

I'd like to use the setInterval function in jQuery in order to create an alert with the content of one array every 4 seconds. However my alerts show all the values of my array within a short amount of time and it stops for 4 seconds after having displayed all the values.

$.each(['html5', 'EDM', 'Coca Cola', 'creativity'], function(id,value) {
    setInterval(function(){
        alert(value);
    }, 4000);
});

In this case, I'd like to display something like : Alert('html5') - 4 seconds - Alert('EDM') - 4 seconds - Alert('Coca Cola') - 4 seconds - Alert('creativity') - 4 seconds - Alert('html5') - 4 seconds - Alert('EDM') - 4 seconds - ...

Upvotes: 3

Views: 8020

Answers (3)

Spudley
Spudley

Reputation: 168695

Use of setInterval is discouraged. For an explanation, read here: http://bonsaiden.github.com/JavaScript-Garden/#other.timeouts

To summarise the problem:

setInterval fires the event at a regular interval, regardless of what else is happening on the page.

However, Javascript is not multi-threaded: it can only run one code sequence at a time. If setInterval is triggered while another code sequence is being run, the new code sequence will be blocked until the previous one is finished, and will wait for it.

If this happens repeatedly, you can end up with a large number of events waiting to be run.

You're using alert() to display your messages. alert() causes the code execution sequence to pause until the user responds to the message, but keeps it locked, so that other events cannot run their code. This is a particular problem for setInterval, because it fires new events at the specified time, regardless of whether something else is blocking the script.

The solution is to use setTimeout instead of setInterval.

setTimeout is only triggered once, but it is easy to tell it to trigger itself again inside its own function, so you can get the same effect as setInterval, but with much more control. Your code can wait until after the alert() has been accepted by the user before triggering the next event, which means that you won't get the problem of cascading events that can happen with setInterval.

Hope that helps explain things. The link I mentioned at the beginning is also very helpful.

Upvotes: 1

SeanCannon
SeanCannon

Reputation: 77976

Use a recursive setTimeout

var arr = ['html5', 'EDM', 'Coca Cola', 'creativity'];
var alertLoop = function(i) {
    if (arr[i]) {
        alert(arr[i]);
        setTimeout(function(){alertLoop(i+1);}, 4000);
    }
}
alertLoop(0);

Demo: http://jsfiddle.net/B5tJw/

Upvotes: 4

gdoron
gdoron

Reputation: 150253

Move the setInterval from the loop.

var arr = ['html5', 'EDM', 'Coca Cola', 'creativity'];
var index = 0;
setInterval(function() {
    console.log(arr[index++ % arr.length]);
}, 4000);​

Live DEMO
No jQuery needed.

Upvotes: 7

Related Questions