Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

494
Visualizações
How to show/hide animated GIF during the execution of a function?

I want to display an animated GIF (spinner icon) during the execution of a function and then hide the GIF when the function is completed.

However, the code that I'm implementing does not display the GIF apparently because the function is hogging the thread and not allowing the GIF to ever be shown.

Example: (https://jsfiddle.net/jzxu8cLt/)

HTML
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">
JS
function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = longLoop();
  resultElement.innerHTML = result;
  spinnerElement.style.display = 'none';
}

The go() function above should do the work of showing the GIF prior to calling a long running function, then will hide the GIF when the long running function is completed.

However, the GIF never has a chance to be displayed in the browser and I can't figure out how to get the GIF to be displayed. Note: If I place a breakpoint at the line that calls the longLoop() function, the GIF is displayed correctly.

What do I need to do to allow the GIF to be displayed and animated during the longLoop() function?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Yep you're right, since JavaScript is single-threaded, the longLoop function is blocking the event loop and not giving the browser a chance to render the gif.

JsFiddle solution: https://jsfiddle.net/12yf4tgd/

I used setTimeout to make the longLoop function asynchronous and wrap that in a Promise so that the other assignments run after it completes.

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';

  new Promise(resolve => setTimeout(() => {
    resolve(longLoop())
  }))
  .then((result) => {
    spinnerElement.style.display = 'none';
    resultElement.innerHTML = result;   
  })
}

Since it is being handled elsewhere by some Web Api and not on the main call stack, it won't be blocking.

If you don't want to use .then() because of all the nesting, the other option is to make go() and async function to take advantage of async/await syntax.

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => resolve(longLoop()))
  })
  spinnerElement.style.display = 'none';
  resultElement.innerHTML = result;
}

They both work the same way.

about 4 years ago · Juan Pablo Isaza Relatório

0

Run your long running and revert code in a setTimeout with timing param omitted or 0 which will execute "immediately", or more accurately, the next event cycle, which will prevent the blocking.

function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  setTimeout(() => {
    let result = longLoop();
    resultElement.innerHTML = result;
    spinnerElement.style.display = 'none';
  })
}
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">

about 4 years ago · Juan Pablo Isaza Relatório

0

I will recommend use async/await for you pourpuse will be more readable code here a solutions:

function longLoop(timeout) {
  return new Promise(resolve => setTimeout(resolve, timeout));
}

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await longLoop(4000);
  
  spinnerElement.style.display = 'none';
 
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda