Асинхронность js (подвисание скрипта)

198
27 ноября 2021, 23:10

Подскажите пожалуйста, как предотвратить временного зависания скрипта во время работы цикла. Насколько я знаю, нельзя параллельно работать с DOM, тогда возник вопрос, а как тогда? Пока функция build(full) занята своими делами, хочется заняться ещё чем нибудь полезным.

function go(){ 
  containerHTML = document.querySelector(".container").style.display = "none"; 
  t0 = performance.now(); 
  for (let i=0; i<1000; i++){} 
  t1 = performance.now(); 
  let i = 0; 
  let goTimer; 
  goTimer = setInterval(()=>{timevis.innerText = i; i++; if(i>100)clearTimeout(goTimer);},(t1-t0)*1500) 
  build(); 
} 
async function build(){ 
  pixel = +pixel.value; 
  canvas = document.getElementById("mainCanvas"); 
  canvas.width = window.innerWidth; 
  canvas.height = window.innerHeight; 
  canvas = canvas.getContext('2d'); 
  for(let i=0;i<window.innerWidth;i+=pixel) 
    for(let j=0;j<window.innerHeight;j+=pixel){ 
      canvas.fillStyle = `rgb(${Math.random()*256},${Math.random()*256},${Math.random()*256})`; 
      canvas.fillRect(i, j, pixel, pixel); 
    } 
}
<canvas id="mainCanvas"></canvas> 
<div class="container"> 
      <h4>Введите сторону квадратов</h4> 
      <input type="number" id="pixel" min="1" value="1"><b>px</b><br> 
      <button onclick="go()">Отрисовать все сразу</button> 
</div> 
<h1 id="timevis"></h1>

Answer 1

Можно вместо цикла использовать таймер и вызывать функцию повторно. И за раз отрисовывать какое-то количество блоков, тогда можно убрать подвисание, например:

function go(){ 
  containerHTML = document.querySelector(".container").style.display = "none"; 
  let i = 0; 
  let goTimer = setInterval(()=>{timevis.innerText = i; i++; if(i>100)clearTimeout(goTimer);},20) 
  let canvas = document.getElementById("mainCanvas"); 
  canvas.width = window.innerWidth; 
  canvas.height = window.innerHeight; 
  build(); 
} 
function build(count = 1000, i = 0, j = 0, pix = +pixel.value, canvas = document.getElementById("mainCanvas").getContext('2d')){ //count - здесь типо количество отрисовываемых блоков за раз 
  for (let k=0; k<count; k++){ 
    canvas.fillStyle = `rgb(${Math.random()*256},${Math.random()*256},${Math.random()*256})`; 
    canvas.fillRect(i, j, pix, pix); 
    if (j<window.innerHeight) j+=pix; else {j=0; i+=pix;} 
    if (i<window.innerWidth) ; else return; 
  } 
  setTimeout(build, 2, count, i, j, pix, canvas); //запускаем еще раз 
}
<canvas id="mainCanvas"></canvas> 
<div class="container"> 
      <h4>Введите сторону квадратов</h4> 
      <input type="number" id="pixel" min="1" value="1"><b>px</b><br> 
      <button onclick="go()">Отрисовать все сразу</button> 
</div> 
<h1 id="timevis"></h1>

READ ALSO
Как показать блок полностью при первом клике и раскрыть его на весь экран при повторном?

Как показать блок полностью при первом клике и раскрыть его на весь экран при повторном?

Как реализовать плавное выдвижение блока с помощью Jquery? Но нужно не просто скрыть/показать, а изначально должна быть видна верхняя часть...

310
Проверка на число в функции

Проверка на число в функции

Нужно сделать так чтобы когда вводят не число, в функцию prime, появилось сообщение, что нужно ввести только число

148
Записать массив числовых значений в таблицу состоящую из инпутов

Записать массив числовых значений в таблицу состоящую из инпутов

Помогите решить такую задачуИмеется массив, состоящий из 9 числовых значений например: var readyArray = [1, 0, 4, 2, 0, 1, 6, 2, 0]; Нужно записать данный массив...

210