Статьи

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

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

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

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

function ProcessArray(data, handler, callback) { 

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

  1. данные: массив элементов для обработки
  2. обработчик: функция, которая обрабатывает отдельный элемент данных
  3. обратный вызов: необязательная функция, вызываемая, когда вся обработка завершена.

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

 var maxtime = 100; // chunk processing time var delay = 20; // delay between processes var queue = data.concat(); // clone original array 

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

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

 setTimeout(function() { var endtime = +new Date() + maxtime; do { handler(queue.shift()); } while (queue.length > 0 && endtime > +new Date()); 

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

примечание: зачем использовать do…while?

JavaScript поддерживает как циклы while, так и циклы do… while. Разница в том, do…while циклы do…while гарантированно выполняют хотя бы одну итерацию. Если бы мы использовали стандартный цикл while, разработчик мог бы установить maxtime или отрицательное maxtime , и обработка массива никогда не началась бы или не завершилась.

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

 if (queue.length > 0) { setTimeout(arguments.callee, delay); } else { if (callback) callback(); } }, delay); } // end of ProcessArray function 

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

Мы можем протестировать ProcessArray() с помощью небольшого тестового примера:

 // process an individual data item function Process(dataitem) { console.log(dataitem); } // processing is complete function Done() { console.log("Done"); } // test data var data = []; for (var i = 0; i < 500; i++) data[i] = i; // process all items ProcessArray(data, Process, Done); 

Код будет работать в любом браузере, включая IE6 +. Это жизнеспособное кросс-браузерное решение, но HTML5 предоставляет гораздо более приятное решение! В моем следующем посте мы обсудим веб-работников …