Как обрабатывать большие объемы данных в JavaScript

Попытка обработки больших объемов информации за один раз может привести к зависанию приложения и принудительному завершению работы приложения со стороны браузера. Как избежать сообщений «Скрипт не отвечает»?

» » Категория: WEB-Разработка / HTML, CSS, PHP, JScript

Как обрабатывать большие объемы данных в JavaScript
Как обрабатывать большие объемы данных в JavaScript

Несколько лет назад разработчики даже не задумывались об альтернативах сложной обработки данных на стороне сервера. Теперь же все изменилось, и многие Ajax-приложения обмениваются большим количеством данных между клиентом и сервером. Кроме того, программный код приложения может изменять объектную модель документа (DOM), что требует особенно много времени для обработки браузером. Однако, попытка обработки больших объемов информации за один раз может привести к зависанию приложения и принудительному завершению работы приложения со стороны браузера.

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

Код: Выделить всё Развернуть
function ProcessArray(data, handler, callback) {

Функция ProcessArray() имеет три аргумента:

  • data: массив элементов для обработки;
  • handler: функция, применяемая для обработки каждого отдельного элемента массива;
  • callback: дополнительная функция, вызываемая после полной обработки массива.

Теперь мы определим переменные конфигурации:

Код: Выделить всё Развернуть
var maxtime = 100; // время обработки блоков массива
var delay = 20; // задержка между двумя процессами обработки блоков
var queue = data.concat(); // копия исходного массива

Переменная maxtime определяет максимальное время в миллисекундах, разрешенное для обработки каждого блока массива. Переменная delay задает время в миллисекундах между процессами обработки отдельных блоков массива. Переменная queue является копией исходного массива с данными, в которой в принципе нет необходимости в большинстве случаев. Однако, так как массив передается в функцию по ссылке, и мы с каждой обработкой нового элемента выталкиваем его из массива функцией shift, эта копия в нашем случае нужна для сохранности данных исходного массива во время обработки.

Теперь мы можем использовать функцию setTimeout для начала обработки:

Код: Выделить всё Развернуть
setTimeout(function() {
 var endtime = +new Date() + maxtime;
 do {
 handler(queue.shift());
 } while (queue.length > 0 && endtime > +new Date());

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

Наконец, мы определяем, остались ли элементы в массиве, которые нужно обработать, и, если обработка необходима, вызываем функцию обработки массива после короткой задержки:

Код: Выделить всё Развернуть
 if (queue.length > 0) {
 setTimeout(arguments.callee, delay);
 }
 else {
 if (callback) callback();
 }
 }, delay);
}
// конец функции ProcessArray

Функция callback выполнится один раз, после обработки всех элементов массива.

Теперь можно протестировать функцию ProcessArray() на сгенерированном наборе данных:

Код: Выделить всё Развернуть
// обработка отдельного элемента массива
function Process(dataitem) {
 console.log(dataitem);
}
// функция, вызываемая после завершения обработки
function Done() {
 console.log("Готово");
}
// тестовые данные
var data = [];
for (var i = 0; i < 500; i++) data[i] = i;
// обработка элементов массива
ProcessArray(data, Process, Done);

Приведенный код работает во всех браузерах, включая IE6+. Это эффективное кроссбраузерное решение, однако в будущем HTML5 предоставит нам более подходящее решение.

© blogs.sitepoint.com

  • 5.00
0 комментариевПросмотров: 180 | Теги: JavaScriptРазработкаОптимизация