0

I have a frequently-firing event in Javascript. Although it is called roughly once-per-second, variations in timing mean I can't use setInterval and instead have a setTimeout function.

It's 'recursive' in that the function I run with setTimeout itself contains a setTimeout to schedule the function to run again.

One thing that I noticed is that when debugging, the stack contains all of the old calls - if I'm calling once every second and I run for 10 seconds, I've got 10+ items in the stack.

I'm concerned there will be an overflow if this keeps running for a long time (which its expected to do).

Is there a way to structure the code so that the stack doesn't grow when setTimeout is being called 'recursively'? Do I simply have a local function being declared somewhere that I need to turn into something global?

Key pieces of information - I'm using BIND, and the recursion is happening from a class function.

I think that using bind might be the issue.


In this case, I'm using BIND

var recclass = {};
recclass.timerid = 0;
recclass.iterations = 0;

recclass.Update = function() 
{
    this.timerid = 0;
    this.iterations++;
    console.log("Iterations: " + this.iterations);
    this.timerid = window.setTimeout(this.Update.bind(this),100);
}

function StartTimers()
{
    recclass.Update();
}

There are a LOT of setTimeouts in the stack when I place a debug point inside the Update function.

Update

The same seems to happen even if I use a global variable to hold my class and don't use //bind// or //this//...

var recclass = {};
recclass.timerid = 0;
recclass.iterations = 0;

recclass.Update = function() {
    recclass.timerid = 0;
    recclass.iterations++;
    console.log("Iterations: " + recclass.iterations);  
    recclass.timerid = window.setTimeout(recclass.Update,100);
}

function StartTimers()
{   
    recclass.Update();
}

Another Update

It's possible that the stack is being pruned automatically - while I do get a number of items in the stack trace, it seems to cap at 25.

As long as Chrome and the console.trace() function aren't limited to stack sizes of 25, it might be that it's cleaning up old setTimeout contexts and the stack isn't actually growing out-of-control.

Perhaps this is some kind of virtual rather than physical call stack (ie it's not really adding to the stack, just noting down the code flow path, to allow developers to understand where the setTimeout calls are coming from.)

A little misleading to read, though.

5
  • Without your code, it's tough to determine the issue. The standard recursive setTimeout pattern should not lead to a growing call stack. Commented Sep 5, 2023 at 0:10
  • Why not set the interval to 0.01 seconds and just check? Commented Sep 5, 2023 at 0:17
  • Added code example. I'd imagine it's due to my use of 'bind'. Commented Sep 5, 2023 at 1:04
  • 1
    The stack trace that you see in your dev tools is not the "real" stack, it's entirely a dev-tools feature. In Chrome you can disable it by running the Do not capture async stack traces command. The JS engine won't keep that stack. Commented Sep 5, 2023 at 1:25
  • Ahh, just reached the 'I hope that is the case' in my fiddling. Thanks for getting back to me. Commented Sep 5, 2023 at 1:35

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.