Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Memory Leak при работе с $.getJSON и циклом $.each (https://javascript.ru/forum/jquery/36092-memory-leak-pri-rabote-s-%24-getjson-i-ciklom-%24-each.html)

Fareastaz 04.03.2013 09:09

Memory Leak при работе с $.getJSON и циклом $.each
 
Здравствуйте,
у меня к вам такой вопрос. Пишу скрипт для циклического отображения данных на странице из файла JSON и вставляю их с помощью двух функций. В первой использую цикл для прохода по всем элементам json файла а так же вызываю ее же в качестве рекурсии для цикличного прохода. Во второй добавляю 5 ненумерованных списков на страницу с тремя значениями. а также удаляю первый из низ для создания анимации (прогона элементов снизу вверх). Проблема в следующем:
Скрипт начинает есть много ресурсов как процессора так и памяти и как я понял функция .remove() не очищает память за собой. Скажите как можно изменить этот цикл или произвести очистку памяти после вывода 5 элементов списка не убивая сам цикл. Требуется чтобы данные циклично отображались. Функция остановки которую я установил на нажатие кнопки делает паузу но не останавливает цикл и так же не очищает память (как лучше поступить с функцией паузы цикла?)

Сам скрипт:

<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="content-type" content="text/html" />
	<meta name="author" content="Viacheslav" />
    <script src="js/jquery-1.7.1.min.js"></script>
	<title>JSON TEST-1</title>
</head>

<body>

  <div id="content_div">
        <ul></ul>  
  </div>
<input type=button value="pause/play" onclick="continue_reporting = ( continue_reporting == 1 ) ? 0 : 1;">
    <script type="text/javascript">        

        var counter = 0;
        var delay_entry = 0;
        delay_fetch = 0;
        var continue_reporting = 1;      
        var node_list = new Array( );
        //var content_div = $("#content_div");
        var child = 0;
       
        
        fetch_data(); // initial run
        function fetch_data()
        {

          $.getJSON('js/list.json?i=' + Math.random(), function(data){
              //console.log("data.length: " + data.length );
              $.each(data, function(key,value){
                counter++
                setTimeout( pusher, 1000 * delay_entry, value );
                delay_entry++;                
                
              })

              

          })  
          setTimeout( fetch_data, 1000 * delay_fetch );
          delay_fetch++;
            
        }
        
        function pusher( value )
        {      
          
            if ( continue_reporting == 1 ) 
            {
              $("#content_div").append("<ul>" + 
                                    "<li>" +  value.reg + "</li>" +
                                    "<li>" +  value.bids[0].ind + "</li>" +
                                    "<li>" +  value.bids[0].v + "</li>" +
                                "</ul>");
                child++;             
              
               if (child > 4){
              $("#content_div ul:first-child").remove();              
              }
                
              }
              console.log("children = " + child);
              
        }
        
        
    </script>
      


</body>
</html>

skynet-mfd 04.03.2013 12:27

зачем рекурсия?

Fareastaz 04.03.2013 16:28

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

skynet-mfd 04.03.2013 17:33

содержание js/list.json?i=' + Math.random() постоянно меняется и его нужно постоянно перечитывать?

skynet-mfd 04.03.2013 17:34

я бы вывел setTimeout( fetch_data, 1000 * delay_fetch ); за пределы fetch_data()

skynet-mfd 04.03.2013 17:41

$.getJSON выполняется асинхронно и setTimeout( pusher, 1000 * delay_entry, value ); тормозит только вызов функции pusher и не тормозит функцию fetch_data, она выполняется соглассно таймеру setTimeout( fetch_data, 1000 * delay_fetch ); и если она еще в рекурсии ... то не удивительно что браузер падает на коленки

danik.js 04.03.2013 17:42

Цитата:

Сообщение от skynet-mfd
содержание js/list.json?i=' + Math.random() постоянно меняется и его нужно постоянно перечитывать?

??

skynet-mfd 04.03.2013 17:44

т.е. другими словами fetch_data() не ждет завершения $.getJSON

skynet-mfd 04.03.2013 17:52

Цитата:

Сообщение от danik.js (Сообщение 238712)
??

ну ты же тут получаешь какой то json массив этим запросом? я про его содержание....

danik.js 04.03.2013 18:03

Я ничего не получаю. Просто мне тоже интересно. Очень надеюсь на ответ «да».

skynet-mfd 04.03.2013 20:23

Цитата:

Сообщение от danik.js (Сообщение 238724)
Я ничего не получаю. Просто мне тоже интересно. Очень надеюсь на ответ «да».

блин... я думал это топикстартер пишет :))

Fareastaz 06.03.2013 08:07

Ссори за отсутствие я топикстартер, вернулся :)

вобщем проблему нагрузки решил немного другим способом, изменил немного код. Но вопрос все равно остался нерешенный, напишу снизу после кода.

<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="content-type" content="text/html" />
	<meta name="author" content="Viacheslav" />
    <script src="js/jquery-1.7.1.min.js"></script>
    <link rel="stylesheet" type="text/css" href="css/style.css">
	<title>JSON TEST-1</title>
</head>

<body>

  <div id="content"></div>

<input type=button value="pause/play" onclick="continue_reporting = ( continue_reporting == 1 ) ? 0 : 1;">
    <script type="text/javascript">        
        
        //Global Variables        
        var continue_reporting = 1;        
        var bids_displayed = 5;
        var uls;
        var data;        
        fetch_data(); // initial run

        function process_data(data){
          var delay_entry = 0;
          $.each(data, function(key, value){            
            setTimeout(function(){pusher(value)}, 1000 * delay_entry);//sending parameter for crappy IE
            delay_entry++;
          })
        }

        function fetch_data(){
            //$.getJSON('js/list.json?i=' + Math.random(), process_data);            
            var url = 'js/list.json';

//the same as getJson
            $.ajax({
                url: url /*+ Math.random()*/,
                cache: false,
                dataType: 'json' ,
                data: data,
                success: process_data
              });
            
           setTimeout(fetch_data, 1000);
           //setTimeout(function(){fetch_data}, 1000);
          }

        function pusher(data){
            if ( continue_reporting == 1 ){
                
                //######### REMOVE CONSOLE.LOG BEFORE TESTING IN IE (почемуто гадина не работает в до боли любимом IE)
                console.log("data.bids.length: " + data.bids.length );

                var main_ul = "<ul class='bid_density'>";
                main_ul += "<li class='bid_region'><span class='bid_region_city'><a href='www.google.com' rel=''>" + data.reg + "</span></a><span class='bid_region_bid'>Bid</span></li>";
                for( var i = 0; i < data.bids.length; i++ ){
                    main_ul += "<li class='bid_industry'><span class = 'bid_ind_title'><a href='#' rel=''>" + data.bids[i].ind + "</span></a><span class='bid_ind_value'>" + data.bids[i].v + "</span></li>";                    
                }

                main_ul += "</ul>";
                $("#content").prepend(main_ul).find("ul:first");
                uls = $("#content").children();
                    
                    //Counting elements and substracting last one                                      
                    if (uls.length>5){
                    $(uls.get(uls.length-1)).remove();
                
                }

                

            } 
                        
        } // end of pusher function 

    </script>
      


</body>
</html>

Проблема все в той же рекурсивной функции Если ее убрать то скрипт после обхода всего JSON файла останавливается и повторно не работает так как больше ничего его не вызывает. Если оставить то данные начинают появляться слишком быстро вне зависимости от таймаута так как скрипт прощелкивает файл грузит его как я понимаю (или недопонимаю) в память и вывод данных по function pusher начинает проходить рывками показывая списки UL не по одному а по три 5 и сразу все.

Уважаемые знатоки, подскажите пожалуйста как можно вызвать эту фунцкцию fetch_data не рекурсией а только после прохода всех данных из файла JSON то есть как задать ей условия запуска заново но только после того как прошла весь файл JSON? Надеюсь объяснил понятно. Сама идея скрипта должна выглядеть вроде этого сайта (правый столбец) http://indexssp.com/


Часовой пояс GMT +3, время: 12:33.