4

I want to make a value on an HTML page that will be updated every 5 seconds so as to not overwhelm the server. It turns out that setTimeout() inside my function is not delaying properly, but is instead being called immediately. Can someone help me find a clue? I really don't want to give my server too much work because I have to implement a lot more AJAX.

Here's the code:

window.onload = function GetUsersNumber() {
    aside = document.getElementById("users");
    if (XMLHttpRequest) var x = new XMLHttpRequest();
    else var x = new ActiveXObject("Microsoft.XMLHTTP");
    x.open("GET", "users_count.php", true);
    x.send();
    x.onreadystatechange = function () {
        if (x.readyState == 4) {
            if (x.status == 200) aside.innerHTML = x.responseText;
            setTimeout(GetUsersNumber(), 50000);
        }
    }
}
Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
DualCore
  • 400
  • 1
  • 3
  • 15
  • possible duplicate of [Calling setTimeout in a loop not working as expected](http://stackoverflow.com/questions/19714453/calling-settimeout-in-a-loop-not-working-as-expected) –  Dec 25 '14 at 02:30
  • Also http://stackoverflow.com/questions/15682524/settimeout-in-nodejs-loop and several other question. –  Dec 25 '14 at 02:31
  • @torazaburo: Neither of those is exactly canonical. This one may not be either, but I think it's now in pretty decent shape to be duped to, although any more tweaks would probably still be helpful. – Nathan Tuggy Dec 25 '14 at 08:12
  • @Nathan: A complicating factor is the `for` loop in the other questions that is not present here. – icktoofay Dec 26 '14 at 01:27

2 Answers2

4

A function object in JavaScript is one thing. A function call is a different thing. You're using the latter, by including parentheses after the function name*, but you need the former, without parentheses. This allows setTimeout to later invoke the function itself by using the passed-in object. Assuming you do actually want 5 seconds (rather than the 50 seconds the original code was using):

setTimeout(GetUsersNumber, 5000);

*Really, any old variable that holds a function object can be invoked like that, but for convenience, defining a function also defines a variable name for it.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
3

setTimeout takes a function as parameter. What you are doing is executing the function right away and passing is returned value of the exected function. Pass GetUsersNumber instead of GetUsersNumber(). () will already execute the function.

setTimeout(GetUsersNumber, 50000);

On a side note:

  • Most of the modern browsers support XMLHttpRequest natively. So, using ActiveXObject is not required.
  • For older browsers, the if condition will anyways give error. Do this: if(window.XMLHttpRequest)
gp.
  • 8,074
  • 3
  • 38
  • 39