Почему Javascript вызывает сбой моей страницы?

#c# #asp.net-mvc #slickgrid

#c# #asp.net-mvc #slickgrid

Вопрос:

итак, я использую MVC 4 C # / Razor и разрабатываю страницу, которая использует SlickGrid для отображения данных сетки. Все работает нормально, за исключением случаев, когда я пытаюсь использовать его для отображения большого объема данных (что-то вроде 1 миллиона строк).

Когда это происходит, кажется, что все работает нормально, пока не будет почти закончено. Как раз в тот момент, когда кажется, что это будет сделано со всей загрузкой данных, веб-страница выходит из строя. Я использую getJSON для извлечения данных из базы данных SQL. Я делаю это по столбцам и партиями по 300000 записей. Я пробовал использовать инструменты профилирования памяти Chrome и не смог найти ничего полезного. Ниже приведены некоторые фрагменты кода:

     function pullAllGridData(tableName, colArray)
    {
        for (var i = 0; i < colArray.length; i  )
        {
            fetchColumn(tableName, colArray[i], 0);
        }
    }


    function fetchColumn(tableName, fieldName, startAt)
    {
        $.getJSON('/WIMenu/GetTableData', { tableName: tableName, fieldName: fieldName }, function (data)
        {
            if (data.slice(-1) !== '~')
            {
                var startPass = populateSlickData(data, fieldName, startAt);
                colStatus[fieldName] = true;
                if (loadFirstBatch())
                { populateGrid(); }
                fetchColumn(tableName, fieldName, startPass);
            }
            else
            {
                data = data.slice(0, -1);
                populateSlickData(data, fieldName, startAt);
                colStatus[fieldName] = true;
                if (loadFirstBatch())
                { populateGrid(); }
            }
        });
    }

    function populateSlickData(input, fieldName, startAt)
    {
            var output = startAt;
            var valueArray = input.split('|');
            output  = valueArray.length;
            if (!isInBlackList(fieldName, tableName))
            {
                var datatype = columns[getColumnIndex(fieldName)].datatype;
                var startIndex = startAt;
                var endIndex = startAt   valueArray.length;
                var counter = 0;
                alert(fieldName   ': startIndex: '   startIndex   ' endIndex: '   endIndex   ' count: '   endIndex-startIndex);
                for (var x = startIndex; x < endIndex; x  )
                {
                    if (!slickdata[x])
                    { slickdata[x] = {}; }
                    if (valueArray[x - startAt] == 'null') { valueArray[x - startAt] = ''; }
                    if (datatype == 'System.DateTime')
                    {
                        if (valueArray[x-startAt] !== '')
                        {
                            var date = new Date(valueArray[x - startAt]);
                            valueArray[x - startAt] = (date.getMonth()   1)   '-'   date.getDate()   '-'   date.getFullYear();
                        }
                    }
                    else if (datatype == 'System.Decimal' || datatype == 'System.Int32' || datatype == 'System.Int16' || datatype == 'System.Int64')
                    {
                        valueArray[x - startAt] = parseFloat(valueArray[x - startAt]);
                    }
                    slickdata[x][fieldName] = valueArray[x - startAt];
                    counter  ;
                }
            }
            currentColumn = fieldName;

        filteredData = slickdata;
        return output;
    }
  

fetchColumn использует рекурсию для продолжения получения данных столбца, пока все они не будут получены. Метод populateGrid просто синхронизирует объект SlickGrid с объектом slickdata. Моя цель здесь — выяснить, почему происходит сбой страницы, и узнать, как это можно исправить.

При использовании оповещений кажется, что в какой-то момент он застревает в цикле for в методе populateSlickData, и я не могу понять, почему. Я пробовал печатать данные для индексации, но, похоже, все нормально.

Комментарии:

1. Действительно интересно, действительно ли рекурсия необходима? Не было бы более эффективным выполнить только один вызов ajax и вернуть все?

2. @gustavodidomenico — Я не вижу никакой рекурсии в примере… Действительно, обратный вызов снова вызывает функцию out, но я бы не назвал это рекурсией.

3. Примечание: В других профессиях это может называться нагрузочным тестом крыла … Действительно, любая часть программного / аппаратного обеспечения сломается, если вы приложите к ней достаточную нагрузку. Некоторые более устойчивы, но действительноли 1 миллион записей для показа в браузере?

4. Я думаю, что людям не хватает леса для деревьев. Он одновременно загружает В ПАМЯТЬ МИЛЛИОН строк данных.

5. Миллион строк из JSON в браузере. Сервер, конечно, может справиться с такой нагрузкой, но даже если браузер может хранить столько данных / много объектов, рендеринг не пройдет должным образом.

Ответ №1:

Вы не можете перенести миллион строк данных в память и ожидать, что любая веб-страница будет выполнять что-либо иное, кроме замедления обхода или даже сбоя. Для этого и предназначена подкачка по сетке в сочетании с ajax по требованию. Ваша сетка должна извлекать данные, необходимые для отображения текущей страницы данных, только при изменении страницы. Вы не должны загружать все заранее.

Вот пример на сайте SlickGrid github:http://mleibman.github.io/SlickGrid/examples/example4-model.html

Вот дополнительная информация:https://github.com/teleological/slickback/wiki/Pagination

Комментарии:

1. Хммм, я думал, что подкачка страниц была встроена в SlickGrid внутренне… Я думаю, что вы, возможно, указали мне правильный путь.

2. разбивка на страницы встроена в slickgrid, но вам нужна комбинация разбивки на страницы и загрузки по требованию. Если вы загрузили десять тысяч строк в память, разбиение на страницы возможно, но это все равно десять тысяч строк в памяти, когда вы показываете только пятьдесят одновременно. Вы хотите, чтобы сетка использовала ajax только при переключении страницы. Вы не должны загружать их все заранее 🙂

3. Итак, конечная цель здесь — создать сетку, которая позволит пользователям фильтровать данные в меньших объемах, которые они будут фактически наблюдать и использовать. Похоже, вы хотите сказать, что простой размер объекта slickdata приводит к сбою страницы (пожалуйста, поправьте меня, если я вас неправильно понимаю). Итак, еще раз поправьте меня, если я ошибаюсь, вы говорите, чтобы настроить мое взаимодействие с JSON / веб-сервером только для получения данных с сервера, когда пользователь фильтрует или прокручивает?

4. Я думаю, что собираюсь полностью реструктурировать все это, чтобы функционировать таким образом, чтобы браузер действительно мог справиться. Этот ответ является основой для моего пересмотра. Спасибо @x0n!

5. @peppajack да — именно огромный размер данных, которые вы загрузили в память, вызывает сбой браузера. Конечно, браузеры не должны аварийно завершать работу, но нехватка памяти — хороший способ сделать это.