Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

493
Views
¿Cómo mostrar/ocultar GIF animado durante la ejecución de una función?

Quiero mostrar un GIF animado (icono giratorio) durante la ejecución de una función y luego ocultar el GIF cuando se complete la función.

Sin embargo, el código que estoy implementando aparentemente no muestra el GIF porque la función está acaparando el hilo y no permite que se muestre el GIF.

Ejemplo: ( 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'; }

La función go() anterior debería hacer el trabajo de mostrar el GIF antes de llamar a una función de ejecución prolongada, luego ocultará el GIF cuando se complete la función de ejecución prolongada.

Sin embargo, el GIF nunca tiene la oportunidad de mostrarse en el navegador y no puedo averiguar cómo hacer que se muestre el GIF. Nota: si coloco un punto de interrupción en la línea que llama a la función longLoop(), el GIF se muestra correctamente.

¿Qué debo hacer para permitir que el GIF se muestre y se anime durante la función longLoop()?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Sí, tienes razón, dado que JavaScript tiene un solo subproceso, la función longLoop bloquea el bucle de eventos y no le da al navegador la oportunidad de mostrar el gif.

Solución JsFiddle: https://jsfiddle.net/12yf4tgd/

Usé setTimeout para hacer que la función longLoop fuera asíncrona y la envolví en una Promesa para que las otras asignaciones se ejecuten después de que se complete.

 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; }) }

Dado que está siendo manejado en otro lugar por alguna Web Api y no en la pila de llamadas principal, no se bloqueará.

Si no quiere usar .then() debido a todo el anidamiento, la otra opción es hacer go() y la función asíncrona para aprovechar la sintaxis asíncrona/espera.

 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; }

Ambos funcionan de la misma manera.

about 4 years ago · Juan Pablo Isaza Report

0

Ejecute su código de larga ejecución y reversión en un setTimeout con parámetro de tiempo omitido o 0 que ejecutará "inmediatamente", o más precisamente, el próximo ciclo de eventos, lo que evitará el bloqueo.

 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 Report

0

Recomendaré el uso de async/await para que el código sea más legible aquí y las soluciones:

 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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!