March 22, 2012

How to increase the maximum call stack in Javascript?

Question by shershams

I have an event, which can fire itself. I try to make the code as efficient as possible, but it can hit maximum call stack in some circumstances, which are out of my control. It’s not an infinite stack and it will end at some point, but sometimes it can potentially crashe before it finishes because of the limit.

Will I increase the number of call stack if I set up 2 similar event listeners and split the code? Or what can I do?

UPDATE: It’s on DOM change event (working with Webkit only, so don’t care about other browsers), which can also modify the DOM based on some conditions. I haven’t really hit that limit yet, but theoritically, it potentially can. I’m still optimizing the code to make as less DOM manipulations as possible.

UPDATE 2: I’m including sample (not real) example:

document.addEventListener('DOMSubtreeModified', function(event){

    this.applyPolicy(event);

}, true);

function applyPolicy(event){
    if( typeof event != "undefined" ){
        event.stopPropagation();
        event.stopImmediatePropagation();
    }

    if( !isButtonAllowed ){
        $('button:not(:disabled)').each(function(){

           $(this).attr('disabled', true);

        });
    }
}

This is just a sample code, but even in this case, if you have say 100s of buttons, the call stack will be in 100s too. Note that if you use $('button').attr('disabled', true);, this will cause call stack problem, because jQuery will be trying to modify the DOM infinitely.

Answer by am not i am

While it sounds like you may need to rethink some code, one possibility would be to put a recursive call in a setTimeout at some given interval. This allows you to begin a new call stack.

Take this example…

var i = 0;

function start() {
    ++i;
    var is_thousand = !(i % 1000);

    if (is_thousand)
        console.log(i);

    if (i >= 100000)
        return; // safety halt at 100,000
    else
        start()
}

It just logs to the console at every interval of 1,000. In Chrome it exceeds the stack somewhere in the 30,000 range.

DEMO: http://jsfiddle.net/X44rk/


But if you rework it like this…

var i = 0;

function start() {
    ++i;
    var is_thousand = !(i % 1000);

    if (is_thousand)
        console.log(i);

    if (i >= 100000) // safety halt at 100,000
        return;
    else if (is_thousand)
        setTimeout(start, 0);
    else
        start();
}

Now at every 1,000, the function will be allowed to return and the next call will be made asynchronously, starting a new call stack.

Note that this assumes that function is effectively ended when the recursive call is made.

Also note that I have a condition to stop at 100,000 so we’re not infinite.

DEMO: http://jsfiddle.net/X44rk/1/

Answer by Starx

You can’t, they are browser dependant and quite frankly they have quite a wide range, so no need to worry about that IMO.

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!