timgavin timgavin - 5 months ago 21
jQuery Question

jQuery setInterval Issue

I'm running a function that checks a remote script every second and updates a progress bar. I'm new with

setInterval
and am having an issue with getting it to stop looping after it's done.

I've added
var interval
post function, and
clearInterval(interval);
in several different places - basically like covering my eyes and pinning the tail on the donkey - and have had no success. Where would I set
clearInterval
to stop the loop once
data
has reached 100?

function getProgress(hash) {
setInterval(function() {
$.ajax({
type: 'GET',
url: 'http://domain.com/script.php?hash=' + hash,
cache: false,
dataType: 'json',
success: function(data) {
if (data < 100) {
getProgress();
} else {
$('#progress-bar').hide();
}
},
});
}, 1000);
}

Answer

This is the answer assuming that you are unable to stop the previous intervals. You're calling getProgress method everytime the data < 100. Which calls to another setInterval method, and re-create a new id for that interval.

Let's say that getProgress method called in a loop for more than one time, if you do,

var intervalId;
function getProgress(hash) {
  intervalId = setInterval(function() {..}, 1000);
}

And the next time you want to stop the interval, you'd call clearInterval(intervalId). And this is very wrong. You have more than one interval, and you just happened to stop the last one while the previous ones are still running until data < 100 is false.

I'd suggest to store your interval ids in an array, like..

var intervalIds = [];
function getProgress(hash) {
  intervalId = setInterval(function() {..}, 1000);
  intervalIds.push(intervalId);
}

And if the next time you want to stop interval, you can do it like..

for (var idx in intervalIds) {
   clearInterval(intervalIds[idx]);
}

But, that's just one way to stop all the intervals. What I am trying to say here is your code is ugly. If the reason you're using setInterval method is to wait for 1000 ms to retrieve another data, setTimeout would do the job just fine. And here's a sample to use it and passing the parameter back.

function getProgress(hash){
   $.ajax({
        type: 'GET',
        url: 'http://domain.com/script.php?hash=' + hash,
        cache: false,
        dataType: 'json',
        success: function(data) {
          if (data < 100) {
            setTimeout(function() {
              getProgress(hash);
            }, 1000);
          } else {
            $('#progress-bar').hide();
          }
        },
    });
}