Вывод блока во время выполнения скрипта

Пробовал сделать так:

.disp-none { display:none;}
......
var block= document.getElementById("progress-bar");
block.classList.add("disp-none");
btn.onclick = function() 
{
   block.classList.remove("disp-none");
   draw();
   block.classList.add("disp-none");
} 

Скрипт выполняется секунд 10, формируется изображение в канвасе. Проблема в том, пока выполняется скрипт блок не появляется. Видимо во время работы скрипта html код не меняется(класс disp-none не удаляется). Что делать в таком случае, как вывести блок перед работой скрипта и спрятать после. Без jQuery

function draw(callback) 
{

let fill_bar = block.querySelector(".fill");
let width = 0;

requestAnimationFrame(fill);
function fill() 
{
    width += 1;
    fill_bar.style.width = width + "%";

    if( width >= 2 ) 
    {
    if(callback) 
        callback();
        redraw();

        return; // Анимация в любом случае завершается, с вызовом функции или без.
    }
requestAnimationFrame(fill);
  }
}

Этот код работает, здесь выполняется функция redraw, которая раньше у меня была draw. Но здесь я так понимаю лишнего много, увелечение ширины например. Как лишнее убрать, что бы работоспособность осталась?

function draw(callback) 
{
requestAnimationFrame(fill);
function fill() 
{
    redraw();
    if(callback) 
        callback();
}
}

Так не работает


Ответы (2 шт):

Автор решения: artomich

Сделайте функцию канвас-отрисовки асинхронной: const draw = async () => {...}

→ Ссылка
Автор решения: OPTIMUS PRIME

Видимо во время работы скрипта html код не меняется

block.classList.add("disp-none");
block.classList.remove("disp-none");
block.classList.add("disp-none");

Даже если написать три таких строчки подряд, браузер не станет скрывать, показывать, потом снова скрывать блок. Код выполняется настолько быстро, что к моменту начала отрисовки блока, он сразу будет с классом "disp-none". А в вашем случае, вы всего лишь добавили еще одну строчку draw() которая погоду не меняет: Если он асинхронный, скрипт не обязан тратить время на ожидание его выполнения. Просто запускает функцию и идет дальше выполнять код.

В качестве аргумента draw() можно передать обычную функцию, которую он будет вызывать при завершении анимации:

var block = document.getElementById("progress-bar");

block.classList.add("hide");
btn.addEventListener("click", function() {
  block.classList.remove("hide");

  function onAnimationEnd() {
    block.classList.add("hide");
    console.log("Завершилось!");
  }

  draw(onAnimationEnd);
});

/***/

function draw(callback) {
  let fill_bar = block.querySelector(".fill");
  let width = 0;

  requestAnimationFrame(fill);
  function fill() {
    width += 1;
    fill_bar.style.width = width + "%";
    
    if( width >= 100 ) {
      if(callback) callback();
      return; // Анимация в любом случае завершается, с вызовом функции или без.
    }
    
    requestAnimationFrame(fill);
  }
}
.hide {
  display: none;
}

#progress-bar {
  position: relative;
  width: 300px;
  height: 20px;
  background-color: #ddd;
  overflow: hidden;
}

.fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 20px;
  width: 0%;
  background-color: orange;
}
<button id="btn">Test</button>
<hr>
<div id="progress-bar">
  <div class="fill"></div>
</div>

→ Ссылка