JavaScript Медленное обновление DOM

avatar
erman999
1 июля 2021 в 18:12
49
1
0

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

Вы все знаете, как работает winrar, когда мы что-то архивируем или разархивируем, имена файлов отображаются быстро, а индикатор выполнения движется вперед. Это очень похоже на то, что я пытаюсь сделать. См. изображение ниже.

sample1

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

По этой причине я написал пример кода для быстрого обновления DOM в браузере. У меня возникла та же проблема, с которой я столкнулся в своем электронном проекте. Как мне побороть эту проблему, я никогда не видел ничего подобного и почему это происходит, объясните.

Пример кода здесь. Увеличьте число до 10000 и попробуйте в браузере для лучшего понимания.

var myBtn = document.getElementById('myBtn');
var myDiv = document.getElementById('myDiv');

myBtn.addEventListener('click', function() {
  for (var i = 0; i < 1000; i++) {
    myDiv.innerHTML = i;
    console.log(i);
  }
});
#myDiv {
  border: 1px solid black;
  padding: 30px;
  margin-bottom: 10px;
}

#myBtn {
  padding: 10px;
}
<div id="myDiv"></div>
<button id="myBtn" type="button" name="button">Button</button>
Источник
Niet the Dark Absol
1 июля 2021 в 18:15
0

Javascript является однопоточным. Если он занят циклическим просмотром вашего кода, он не может обновить представление, отображаемое пользователю. Чтобы имитировать этот эффект, вам понадобится какая-то временная петля.

erman999
1 июля 2021 в 18:18
0

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

Niet the Dark Absol
1 июля 2021 в 18:21
0

requestAnimationFrame может работать, но даже при 60 кадрах в секунду показ 1000 элементов займет 16,67 секунды.

Ответы (1)

avatar
D. Pardal
1 июля 2021 в 18:30
0

Чтобы понять, что происходит, вам нужно понять, как работает цикл обработки событий. Поскольку JS — это однопоточный язык, отдельные блоки кода (известные как «задачи») выполняются по очереди, но ни один из них не может прервать другой. Вот почему ваш код не работает. Основной поток застрял в этом цикле и не может ничего делать, пока он не завершится.

Вы можете использовать window.requestAnimationFrame() для анимации текста, но вам, вероятно, следует показать файл, который в данный момент обрабатывается, что и делает WinRar.

const outDiv = document.getElementById("output");

// The each number is displayed. (lower = faster)
const PERIOD = 50;
// The limit.
const MAX = 100;

// The code is written like this so it always runs
// at the same speed. Never increment `i` in the
// handler!
let startTime = performance.now();

function handler(now) {
  const timeDiff = (now - startTime),
        i = Math.min(Math.floor(timeDiff / PERIOD), MAX);
  outDiv.innerText = i;
  if (i < MAX) {
    window.requestAnimationFrame(handler);
  }
}
handler(startTime);
<div id="output"></div>
erman999
1 июля 2021 в 18:49
0

Это именно то, что я пытался сделать. Безупречная работа спасибо.