Проверяет понимание асинхронной обработки больших массивов данных без блокировки пользовательского интерфейса.
Когда вы выполняете синхронный цикл по массиву из 2 миллионов элементов, каждый из которых требует 100 мс обработки, общее время составит около 200 000 секунд (более 55 часов). В течение этого времени главный поток браузера будет полностью занят, и пользовательский интерфейс перестанет реагировать на клики, прокрутку и другие события. Это происходит потому, что JavaScript в браузере работает в одном потоке, и длительные операции блокируют цикл событий.
Основная идея — обрабатывать массив не целиком, а небольшими частями, давая браузеру возможность обновить интерфейс между ними. Для этого можно использовать setTimeout с нулевой задержкой или requestIdleCallback. Каждая порция обрабатывается синхронно, но после неё управление возвращается циклу событий, что позволяет обработать другие задачи.
const data = new Array(2000000).fill(0);
const CHUNK_SIZE = 1000;
let index = 0;
function processChunk() {
const end = Math.min(index + CHUNK_SIZE, data.length);
for (let i = index; i < end; i++) {
// обработка элемента, например, data[i] = heavyOperation(data[i]);
}
index = end;
if (index < data.length) {
setTimeout(processChunk, 0); // планируем следующую порцию
} else {
console.log('Обработка завершена');
}
}
processChunk();Здесь каждая порция из 1000 элементов обрабатывается примерно за 100 секунд (1000 * 100 мс), но между порциями браузер успевает отрисовать изменения и обработать события. Вы можете регулировать размер порции в зависимости от требуемой отзывчивости.
Если обработка не требует доступа к DOM, можно вынести её в отдельный поток с помощью Web Workers. Это полностью освобождает главный поток, но требует передачи данных между потоками, что может быть накладно для больших массивов. Однако для тяжёлых вычислений это лучший вариант.
// worker.js
self.onmessage = function(e) {
const data = e.data;
const result = data.map(item => heavyOperation(item));
self.postMessage(result);
};
// main.js
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = function(e) {
console.log('Результат:', e.data);
};Для обработки больших массивов без блокировки UI используйте разбиение на порции с setTimeout или requestIdleCallback, если операция не слишком тяжёлая. Если же требуется интенсивная вычислительная работа, предпочтительнее Web Workers. Выбор зависит от конкретной задачи и требований к отзывчивости интерфейса.
Уровень
Рейтинг:
4
Сложность:
5
Навыки
JavaScript
Node.js
Ключевые слова
Подпишись на React Developer в телеграм
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию