简体   繁体   中英

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM