开发者

Weird infinite loop bug in jquery recursive function

开发者 https://www.devze.com 2023-03-15 18:39 出处:网络
I have a strange issue on the project I\'m working with. This changes an image source and a content of a div automatically.

I have a strange issue on the project I'm working with. This changes an image source and a content of a div automatically.

I have coded a function, but it falls into infinite loop and page does not load (page is showing the loading page always).

These are the codes:

$.fn.extend({
    changehaber: function(a){
     $('#cokokunanlarcontent').fadeOut('slow',function() {
           $('.jquerycokokunanlarbutton').attr('src','images/sabah/buton-pasif.png');
           $('img[rel="'+a+'"]').attr('src','images/sabah/buton-aktif.png'); 
        }).html($('#'+a).html()).fadeIn('slow');
        return this;
    }
});

function slidecokokunanlar() {
    $('#cokokunanlarcontent').html($('#cokokunanlar1').html()).delay(3000).changehaber('cokokunanlar2').delay(3000).c开发者_如何学JAVAhangehaber('cokokunanlar3').delay(3000).changehaber('cokokunanlar4').delay(3000).changehaber('cokokunanlar5').delay(3000);
    slidecokokunanlar();
}

slidecokokunanlar();

What's the issue here, when this is executed, I want the function to work infinitely, but the page shows it's always loading. This is the console's output:

Uncaught RangeError: Maximum call stack size exceeded

Thanks in advance


You can't call a function from inside itself without blocking up the whole execution stack. By calling the function from inside itself, you're effectively preventing it from ever returning, and as Javascript is single-threaded, everything will grind to a halt!

Change your function to this:

function slidecokokunanlar() {
    $('#cokokunanlarcontent').html($('#cokokunanlar1').html()).delay(3000)...
    setTimeout(slidecokokunanlar, 0);
}

This allows for concurrent execution without blocking the UI, thus allowing your page to remain responsive.

See this article on "chunking" for more information on how this works.


This is because JavaScript doesn't have proper tail calls.

Your function calls itself at the end of itself forever. The first one never finishes and returns, nor does the second, nor do any of them until you run out of stack and explode.

You might try using setTimeout instead. See an example on jsFiddle.

EDIT You might not want to use 0 unless you really need it to be running continuously. Even using 100, you'd execute the function 10 times per second.

function foo(){
  console.log('foo');
  setTimeout(foo, 0);  
}

foo();


Here's a cleaner way to do it.

var coko = $('#cokokunanlarcontent');             // cokokunanlarcontent
var cokos = $('[id^="cokokunanlar"]').not(coko);  // cokokunanlar1..2..3 etc

var total = cokos.length;  // total quantity

var i = 0;

var allow = true;

$('.jquerycokokunanlarbutton').attr('src','images/sabah/buton-pasif.png');

function slidecokokunanlar( isRestart ) {

    if( !isRestart ) {
        $('img[rel="' + cokos[i].id + '"]').attr('src','images/sabah/buton-aktif.png');

        coko.html( cokos.eq(i).html() )
            .fadeIn( 'slow' );
    }
    if( allow ) {
        coko.delay( 3000 )
            .fadeOut('slow', function() {
               i = (++i % total);
               slidecokokunanlar();  // recursively call with next index or 0
            });
    }
}

slidecokokunanlar();  // start it off

function restartSlider() { 
    allow = true;
    slidecokokunanlar( true );
}

function stopSlider() { 
    allow = false;
}

stopSlider();   // to stop it

restartSlider();  // to restart it
0

精彩评论

暂无评论...
验证码 换一张
取 消