Skip to content
Advertisement

Wait until setInterval() is done

I would like to add a small dice-rolling effect to my Javascript code. I think a good way is to use the setInterval() method. My idea was the following code (just for testing):

function roleDice() {
    var i = Math.floor((Math.random() * 25) + 5);
    var j = i;
    var test = setInterval(function() {
        i--;
        document.getElementById("dice").src = "./images/dice/dice" + Math.floor((Math.random() * 6) + 1) + ".png";
        if (i < 1) {
            clearInterval(test);
        }

    }, 50);
}

Now I would like to wait for the setInterval until it is done. So I added a setTimeout.

setTimeout(function(){alert("test")}, (j + 1) * 50);

This code works quite okay. But in my main code the roleDice() function returns a value. Now I don’t know how I could handle that… I can’t return from the setTimeout(). If I add a return to the end of the function, the return will rise too fast. Does anyone have an idea, of how I could fix that?

Edit Hmm, okay I understand what the callback does and I think I know how it works but I have still the problem. I think it’s more of an “interface” problem… Here is my code:

function startAnimation(playername, callback) {
    var i = Math.floor((Math.random() * 25) + 5);
    var int = setInterval(function() {
        i--;
        var number = Math.floor((Math.random() * 6) + 1);
        document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
        if(i < 1) {
            clearInterval(int);
            number = Math.floor((Math.random() * 6) + 1);
            addText(playername + " rolled " + number);
            document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
            callback(number);
        }
    }, 50);
}

function rnd(playername) {
    var callback = function(value){
        return value; // I knew thats pointless...
    };
    startAnimation(playername, callback);
}

The function rnd() should wait and return the value… I’m a little bit confused. At the moment I have no clue how to going on… The code wait for the var callback... but how I could combine it with the return? I would like to run the animation and return after that the last number with rnd() to another function.

Advertisement

Answer

You stumbled into the pitfall most people hit at some point when they get in touch with asynchronous programming.

You cannot “wait” for an timeout/interval to finish – trying to do so would not work or block the whole page/browser. Any code that should run after the delay needs to be called from the callback you passed to setInterval when it’s “done”.

function rollDice(callback) {
    var i = Math.floor((Math.random() * 25) + 5);
    var j = i;
    var test = setInterval(function() {
        i--;
        var value = Math.floor((Math.random() * 6) + 1);
        document.getElementById("dice").src = "./images/dice/dice" + value + ".png";
        if(i < 1) {
            clearInterval(test);
            callback(value);
        }
    }, 50);
}

You then use it like this:

rollDice(function(value) {
    // code that should run when the dice has been rolled
});
Advertisement