setTimeout calls function immediately instead of after delay


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);
        }
    }
}

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.


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)