Gradislava Bikkulova
Gradislava Bikkulova

Reputation: 331

My setTimeout doesn't respect the delay

I want to repeat a function every 10s with setTimeout. My function is:

dateInLive = function() {
    crono = function(){
      setTimeout(function() {
        $('.datePoste').each(function(){
                $(this).load('in_live.php','in_live='+$(this).attr('id'))
            });
        crono();
        }
        ,10000);
    }
    crono();
}

But, it's really random; sometimes it's repeating after 15s, sometimes after 3s, sometimes after 6s.

Upvotes: 0

Views: 977

Answers (5)

adeneo
adeneo

Reputation: 318192

Recall crono() only when all the ajax requests are completed :

function crono(){
    setTimeout(function() {
        var arr = [];
        $('.datePoste').each(function(){
            var self = this;
                xhr = $.get('in_live.php', {in_live : this.id}, function(data) {
                    $(self).html( $.parseHTML(data) );
                });
            arr.push(xhr);
        });
        $.when.apply($, arr).done(crono);
    }, 10000);
}

Upvotes: 2

Kevin B
Kevin B

Reputation: 95022

In this situation, i would use deferred objects.

function crono(){
    setTimeout(function() {
        var defArr = [];
        $('.datePoste').each(function(i,el){
            var deferred = $.Deferred();
            defArr.push(deferred.promise());
            $(this).load('in_live.php','in_live='+$(this).attr('id'), function() {
                 deferred.resolve();
            });
        });
        $.when.apply($,defArr).done(crono);
    }, 10000);
}

Doing it this way will request all sections, then when all sections are received, wait 10 seconds and request them again, avoiding the request from piling up in a slow network situation.

Upvotes: 2

Spudley
Spudley

Reputation: 168685

You're using setTimeout to run a repeated event.

This is correct (others have recommended setInterval instead, but there are issues with this).

However you aren't setting the timeout on the subsequent calls -- you're just calling the crono() function directly, so after the initial timeout delay, it will then just start calling itself immediately over and over and over forever (until it exhausts the stack space).

What you need to do is call setTimeout() each time you call the function. Recode it something like this:

dateInLive = function() {
    crono = function(){
        $('.datePoste').each(function(){
            $(this).load('in_live.php','in_live='+$(this).attr('id'))
        });
        setTimeout(crono,10000);
    }
    setTimeout(crono,10000);
}

Upvotes: 2

shrimpwagon
shrimpwagon

Reputation: 905

You just have the crono() function in the wrong place.

dateInLive = function() {
 crono = function(){
 setTimeout(function() {
        crono();
        $('.datePoste').each(function(){
               $(this).load('in_live.php','in_live='+$(this).attr('id'))
           });
        }
        ,10000);
    }

}

Upvotes: 0

Gung Foo
Gung Foo

Reputation: 13558

you are doing something before creating the new timeout, which means there is bound to be "some" delay.

have a look at the setInterval() function.

Upvotes: 0

Related Questions