26

I have the following JS functions:

function checkIfGameAlreadyStarted(){
    $.get("IsGameAlreadyStarted",null,function(gameAlreadyStarted){
        if (gameAlreadyStarted == "true"){
            window.location = "index.jsp?content=game";       
        } else{
            alert("bla");
        }  
    });
}

function joinGame(playerForm){
    $.get("GenerateClientID",null,function(clientID){         
        $.get("JoinGame",{
            "NAME" : playerForm.elements[0].value,
            "ID" : clientID
        }
        ,function(gameParam){

            $("#waitingContainer").append("You have joined the game!<br\>Waiting for game creator to start game..");
            setInterval(checkIfGameAlreadyStarted(), 1000);    

        });
    });
}

Why does setInterval executes checkIfGameAlreadyStarted only once, and not every second?

MichaelS
  • 7,023
  • 10
  • 51
  • 75
  • See also [Why does the setInterval callback execute only once?](https://stackoverflow.com/q/10182714/1048572). And the same question for `setTimeout` [here](https://stackoverflow.com/q/7137401/1048572) or [there](https://stackoverflow.com/q/3800512/1048572) – Bergi Sep 08 '22 at 21:18

2 Answers2

84

You are passing the result of executing the function instead of the function itself. Since the result of the function is undefined, you are executing checkIfGameAlreadyStarted and then passing undefined to setInterval which doesn't do anything.

Instead of this:

setInterval(checkIfGameAlreadyStarted(), 1000);

Your statement should be this:

setInterval(checkIfGameAlreadyStarted, 1000);

without the parentheses at the end of the function name.

When you pass checkIfGameAlreadyStarted() that calls the function immediately and gets it's return value. When you pass checkIfGameAlreadyStarted that passes a reference to the function so setInterval can call it later (which is what you want).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
7

To use checkIfGameAlreadyStarted without parameters, use the method below:

setInterval(checkIfGameAlreadyStarted, 1000);

In case checkIfGameAlreadyStarted has some parameters to be passed, use the method below:

setInterval(function(){checkIfGameAlreadyStarted(a,b);},1000)

This is the best approach I have seen. Other well tested methods are welcomed ,though.

Edit

Passing parameters after the timeout as suggested in the comments is cool but using the above method I stated helps to combat the bind this problem in case checkIfGameAlreadyStarted() is a class method like this this.checkIfGameAlreadyStarted().

In case you want to pass parameters after timeout, here is how it works,

setInterval(checkIfGameAlreadyStarted, 1000, parameter1, parameter2);
Akintunde
  • 3,525
  • 1
  • 21
  • 23
  • You can also pass parameters after the timeout, though you need a polyfill for IE9-. https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval –  Jan 15 '19 at 01:22