Web Develop Wolf
Web Develop Wolf

Reputation: 6336

Using SetTimeout to Delay a Function in JavaScript

I have a function that checks if to see if a game is over that I want to delay to give the user time to see if each answer is correct before seeing the game over screen.

The game ov er check works fine when it's run with no time out, but when I set the timeout I get the error that the function call is not a function.

setTimeout(function() {this.CheckGameOver();}, (5 * 1000)); 

Is there something wrong with the way the Timeout is being set? That's the only think could be the problem as the function works perfectly on it's own.

CheckGameOver: function() {
        // Check game over clause
        var c = this.View.children;

        if (this.players[0].answered == 13) { // Check if Player 1 won
            // Win the game
            gameStopped = true;
            isFirstQuestionSetup = true;

            if(this.PlayerCount == 1) {
                views.get('singlePlayerGame').transitionOut();
                clearInterval(this.cpu);
            } else {
                views.get('twoPlayerGame').transitionOut();
            }
            views.get('background').switchState(BACKGROUND_STATES.GAME_OVER);
            views.get('genericHud').switchState(HUD_STATES.MAIN_MENU);
            views.get('gameOver').transitionIn(this.players, this.GameType, this.Language);

        } 

        if (this.playerCount == 1) {
            if (this.cpuAnswered == 13) { // Check if CPU won
                // Lose the Game (Doh!)
                gameStopped = true;
                views.get('singlePlayerGame').transitionOut();
                clearInterval(this.cpu);
                views.get('background').switchState(BACKGROUND_STATES.GAME_OVER);
                views.get('genericHud').switchState(HUD_STATES.MAIN_MENU);
                views.get('gameOver').transitionIn(this.players, this.GameType, this.Language);
            }
        } else {
            if (this.players[0].answered == 13) { // Check if Player 2 won
                // Player 2 Wins
                gameStopped = true;
                views.get('twoPlayerGame').transitionOut();
                views.get('background').switchState(BACKGROUND_STATES.GAME_OVER);
                views.get('genericHud').switchState(HUD_STATES.MAIN_MENU);
                views.get('gameOver').transitionIn(this.players, this.GameType, this.Language);
            }
        }
    },

Upvotes: 0

Views: 65

Answers (2)

emiliopedrollo
emiliopedrollo

Reputation: 950

It happens that the anonymous function inside setTimeout is in a different closure than anything outside it thus this is something different and does not have such functions.

You should, outside setTimeout set something like

var that = this;

and inside setTimeout call for that.CheckGameOver() so it will solve your closure problem.

Alternatively, if all you have to do within a delay is to call CheckGameOver you can write your line like this:

setTimeout(this.CheckGameOver, (5 * 1000)); 

Upvotes: 0

baao
baao

Reputation: 73281

this inside the setTimeout function doesn't refer to what you think it does. You can either use an es6 arrow function

setTimeout(() => {this.CheckGameOver();}, (5 * 1000)); 

or bind this to setTimeout

setTimeout(function() {this.CheckGameOver();}.bind(this), (5 * 1000)); 

Upvotes: 2

Related Questions