Странная ошибка бесконечного цикла в рекурсивной функции jquery - PullRequest
3 голосов
/ 28 июня 2011

У меня странная проблема с проектом, с которым я работаю. Это автоматически изменяет источник изображения и содержимое div.

Я закодировал функцию, но она попадает в бесконечный цикл, и страница не загружается (страница показывает страницу загрузки всегда).

Это коды:

$.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).changehaber('cokokunanlar3').delay(3000).changehaber('cokokunanlar4').delay(3000).changehaber('cokokunanlar5').delay(3000);
    slidecokokunanlar();
}

slidecokokunanlar();

В чем здесь проблема, когда это выполняется, я хочу, чтобы функция работала бесконечно, но страница показывает, что она всегда загружается. Это вывод консоли:

Uncaught RangeError: Maximum call stack size exceeded

Заранее спасибо

Ответы [ 3 ]

5 голосов
/ 28 июня 2011

Вы не можете вызывать функцию изнутри себя, не блокируя весь стек выполнения. Вызывая функцию изнутри себя, вы фактически предотвращаете ее возврат, и, поскольку Javascript является однопоточным, все остановится!

Измените свою функцию следующим образом:

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

Это позволяет выполнять параллельное выполнение без блокировки пользовательского интерфейса, что позволяет вашей странице оставаться отзывчивой.

См. эту статью о "чанкинге" для получения дополнительной информации о том, как это работает.

2 голосов
/ 28 июня 2011

Это потому, что JavaScript не имеет правильных вызовов хвоста .

Ваша функция всегда вызывает себя в конце. Первый никогда не заканчивает и не возвращает, ни второй, ни любой из них, пока вы не исчерпаете стек и не взорвитесь.

Вместо этого вы можете попробовать setTimeout. См. Пример для jsFiddle .

РЕДАКТИРОВАТЬ Возможно, вы не захотите использовать 0, если вам действительно не нужно, чтобы он работал непрерывно. Даже используя 100, вы выполняете функцию 10 раз в секунду.

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

foo();
1 голос
/ 28 июня 2011

Вот более чистый способ сделать это.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...