1

I am making a Snake game on my webpage using JavaScript and HTML. In this game I want to call a function after regular time intervals. This function will update and print the position of the snake.

For this I am using setTimeOut(my_function,time).

My code looks like this

function my_function(){
// update values
// display snake
setTimeOut(my_function,time)
}

My question is - Will the above code create a lot of function calls on the function stack like a recursive function. I think it will.

Below is how I think I can optimise it.

function empty_function{
}

while(true){
//update values
//display snake
setTimeOut(empty_function,time)
} 

Will this method will also create a lot of function calls on the function stack like a recursive function?

void_117
  • 86
  • 1
  • 8
  • Does this answer your question? [By using javascript recursive setTimeout function, is it risky to get the stackoverflow?](https://stackoverflow.com/questions/48736331/by-using-javascript-recursive-settimeout-function-is-it-risky-to-get-the-stacko) – Marco Jan 14 '21 at 18:08
  • Yes i think it does. Thanks – void_117 Jan 16 '21 at 11:30

2 Answers2

1

Your optimized solution is actually the one that will crash the program, because it keeps the same function running forever. Your first approach is perfectly fine: setTimeout doesn't call the function immediately but schedules it to be run. In the meantime your process can handle other events and start with a new stack when your function is due to be called.
In your infinite while loop your function will never even be called, as there will never be time for the program to check its scheduled task list.

If your interval is frame based (for example, you wish to update your graphics as often as possible) you might be better off with requestAnimationFrame():

function update(timestamp) {
  // render your game
  // request this function to be run again on the next frame:
  window.requestAnimationFrame(update);
}

window.requestAnimationFrame(update);

As you can see it uses the same approach, but is specifically designed to try and match the refresh rate of the users screen freeing you from having to define the interval between render ticks.

soimon
  • 2,400
  • 1
  • 15
  • 16
0

You can achieve this more easily by setInterval.Here is an example;

setTimeout(() => {console.log('this will get printed only once after 1000 ms')}, 1000);

setInterval(() => {console.log('this will get printed after every 1000 ms')}, 1000);

setInterval runs a function again and again after given interval of time.

If you want to stop the setInterval function, this is how you can do it;

let myinterval = setInterval(() => {console.log('Print this again and again after 1000 ms')}, 1000);

// Down here i am clearing the 'myInterval' interval using the 'clearInterval' function.
const clear = () => {
  console.log('printing stopped');
  clearInterval(myinterval);
}
 
 document.getElementById('stop').addEventListener('click', clear);
<button id='stop'>Stop printing</button>
Irfan wani
  • 4,084
  • 2
  • 19
  • 34
  • Thanks for the answer. Just one more doubt if i make a function func() and then call setTimeOut(func,time) inside it. Will this give me a stackoverflow error after some time? – void_117 Jan 14 '21 at 11:29
  • What the OP wants can perfectly be done by `setTimeout`. The snippet at the top of the question is even a valid approach. – soimon Jan 14 '21 at 11:41
  • @soimon though he can do it like he has done but setInterval is a better option. That is created for the same purpose. So why to create a loop and do that stuff when you can do it in just one line of code – Irfan wani Jan 14 '21 at 11:43
  • True, but at the time I commented you said it would cause a stack overflow. – soimon Jan 14 '21 at 11:47