Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

239
Vistas
Logging progress of loop of promises in HTML is not working

With the code below I'm trying to document the progress of a series of loops.

However, as you will see, the progress is not documented smoothly in the DOM. Lots of percentage increments are being skipped.

How can I fix that ?

;(async () => {
  let width = document.getElementById('width')
  let numOfImages = 8
  let images = Array.from(Array(numOfImages).keys())
  let pixelsPerImage = 3600
  let totalPixels = numOfImages * pixelsPerImage
  let currentLoop = 0

  for (let img of images) {
    await new Promise((resolve) => {
      // this setTimeout is actually an image.onload callback
      setTimeout(() => {
        let i = 0
        while (i < pixelsPerImage) {
          ;(function(cloop) {
            window.requestAnimationFrame(() => {
              let prcnt = ((100/totalPixels) * cloop).toFixed(2)
              width.innerHTML = prcnt + '%'
              width.style.width = prcnt + '%'
            })
          })(++currentLoop)
          i++
        }
        resolve()
      }, 5000)
    })
  }

  await Promise.all(promises)
})()

https://jsfiddle.net/koyfa6pm/1/

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

It look like you are trying to run 8 promises in parallel but they run one after the other.

It goes like this: 8 promises are created, one after the other. each promise registers a setTimeout for 5000ms.

Once the 5000ms are over there will be 8 callbacks waiting, the runtime will call them one after the other (JavaScript is single threaded).

The first promise will do a 3600 loop, and will write to the console.log 3600 times. Then the next promise callback will be called by the runtime, and the next 3600 loop will do the same... till all 8 loops are over.

You see many console.log because you do that 3600*8 times... you don't see the DOM changes because the browser will render only after the execution is complete.

In order to see dom changes, you will have to "release" the execution of your code, you can do that with setTimeout(..., 0) to get the next immediate render. or even better use requestAnimationFrame

You would want to do the minimum every frame to let the browser render it fast. avoid huge loops, slow code.

Next thing you will probably encounter is that the progress speed changes according to your CPU, if you want to be same no matter the CPU power, you would want to start taking time into consideration, which a totally different subject :-)

about 4 years ago · Juan Pablo Isaza Denunciar

0

It slows down the overall progress, as I'm now waiting for the HTML updates to finish before moving on to the next loop but the progress shown in the HTML is now accurate and smooth. It's a trade off.

;(async () => {
  let width = document.getElementById('width')
  let topLoops = 8
  let innerLoops = 3600
  let totalLoops = topLoops * innerLoops
  let currentLoop = 0
  let images = Array.from(Array(topLoops).keys())

  for (let img of images) {
    await new Promise((resolve) => {
      // this setTimeout is actually an image.onload callback
      setTimeout(async() => {
        let i = 0
        while (i < innerLoops) {
          currentLoop++
          await new Promise((resolve) => {
            window.requestAnimationFrame(() => {
              let prcnt = ((100/totalLoops) * currentLoop).toFixed(2)
              width.innerHTML = prcnt + '%'
              width.style.width = prcnt + '%'
              resolve()
            })
          })
          i++
        }
        resolve()
      }, 5000)
    })
  }

  await Promise.all(promises)
})()
#width {
  float:left;
  height: 20px;
  background: red;
  color: black;
  padding: 3px;
}
<div id="width"></div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda