0

I am working on improving my coding skills and came up with a project to complete. It is currently a program where you choose up to 5 directional choices using buttons. Pressing the directional buttons adds that direction to an array. I created a function, startMove() to move a ball on the screen based on the directions in the array. When it is executed, the program moves the ball one direction at a time while pausing in between. I also have a section where an arrow will show up for each direction you input to show what you have queued up. You can view through JSFiddle.

var startMove = function() {
for(var j=0;j<queue.length;j++) {
    spot = queue[j];
    if(spot=="left") {
        (function (j) {
            setTimeout(function () {
                switch(j) {
                    case 0:
                        document.getElementById("one").style.transform = "scale(1.5)";
                        break;
                    case 1:
                        document.getElementById("two").style.transform = "scale(1.5)";
                        break;
                    case 2:
                        document.getElementById("three").style.transform = "scale(1.5)";
                        break;
                    case 3:
                        document.getElementById("four").style.transform = "scale(1.5)";
                        break;
                    case 4:
                        document.getElementById("five").style.transform = "scale(1.5)";
                        break;
                    default:
                        console.log("Length is zero.");
                        break;
                }
                moveCharacter(left);
                console.log("X: "+character.x);
                console.log("Y: "+character.y);
            }, 1000*j);
        })(j);
    }
    else if(spot=="right") {
        (function (j) {
            setTimeout(function () {
                switch(j) {
                    case 0:
                        document.getElementById("one").style.transform = "scale(1.5)";
                        break;
                    case 1:
                        document.getElementById("two").style.transform = "scale(1.5)";
                        break;
                    case 2:
                        document.getElementById("three").style.transform = "scale(1.5)";
                        break;
                    case 3:
                        document.getElementById("four").style.transform = "scale(1.5)";
                        break;
                    case 4:
                        document.getElementById("five").style.transform = "scale(1.5)";
                        break;
                    default:
                        console.log("Length is zero.");
                        break;
                }
                moveCharacter(right);
                console.log("X: "+character.x);
                console.log("Y: "+character.y);
            }, 1000*j);
        })(j);
    }
    else if(spot=="up") {
        (function (j) {
            setTimeout(function () {
                switch(j) {
                    case 0:
                        document.getElementById("one").style.transform = "scale(1.5)";
                        break;
                    case 1:
                        document.getElementById("two").style.transform = "scale(1.5)";
                        break;
                    case 2:
                        document.getElementById("three").style.transform = "scale(1.5)";
                        break;
                    case 3:
                        document.getElementById("four").style.transform = "scale(1.5)";
                        break;
                    case 4:
                        document.getElementById("five").style.transform = "scale(1.5)";
                        break;
                    default:
                        console.log("Length is zero.");
                        break;
                }
                moveCharacter(0, up);
                console.log("X: "+character.x);
                console.log("Y: "+character.y);
            }, 1000*j);
        })(j);
    }
    else if(spot=="down") {
        (function (j) {
            setTimeout(function () {
                switch(j) {
                    case 0:
                        document.getElementById("one").style.transform = "scale(1.5)";
                        break;
                    case 1:
                        document.getElementById("two").style.transform = "scale(1.5)";
                        break;
                    case 2:
                        document.getElementById("three").style.transform = "scale(1.5)";
                        break;
                    case 3:
                        document.getElementById("four").style.transform = "scale(1.5)";
                        break;
                    case 4:
                        document.getElementById("five").style.transform = "scale(1.5)";
                        break;
                    default:
                        console.log("Length is zero.");
                        break;
                }
                moveCharacter(0, down);                    
                console.log("X: "+character.x);
                console.log("Y: "+character.y);
            }, 1000*j);
        })(j);
    }
}
//removeAll();

};

Currently the program works almost perfectly. I even have it so that the arrows grow in size as they are being executed. The section above is the problem. I wanted to edit the startMove() function so that the very last thing it does is hide all the images again and clears the array. I have a function that does this already, removeAll(). I add the call to removeAll() function at the very end of the startMove() function, yet when I run the program, queue up my options, and execute, the ball moves as it's supposed to, but the arrows disappear after the first movement. Why does removeAll() run before the movement is finished? Does it not recognize the pauses I included?

Any help would be appreciated. I still have a lot to learn so if anything else in my code could be done better I would love to hear feedback on that as well. I currently have the call to removeAll() commented out so you can see how the code runs without it. It is one of the last lines of the javascript.

1 Answers1

0

The problem is because your pauses, are actually delayed execution of seperate processes. setTimeout accepts a callback (function) as the first parameter. It waits the number of milliseconds speficied by the second parameter, and then calls the callback function. But it does this in a non-blocking way.

setTimeout(() => console.log("Hello"),5000); // waits 5 seconds then prints 'Hello'
console.log(" World!") // prints ' World' right after the timeout has been set.
// but without waiting the five seconds.

Think of it like setting a timer to take cookies out of the oven, but then pouring a glass of milk while you wait, or in code.

setTimeout(takeCookiesOutOfOven, 30000);
pourGlassOfMilk(); //You don't need to wait for the cookies to do this, so you just do it.

If you want to wait for pauses before executing the next line of code, Look into the async/await and promise modifications made to setTimeout here: Combination of async function + await + setTimeout

sam_ferree
  • 57
  • 5
  • Thank you for the reply and explanation! I didn't know that was how it worked. I'll take a look at the link you provided and make modifications. – Isaac Mack Apr 11 '18 at 17:53