es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué no funciona esta función (esperando un elemento en Javascript)?

Básicamente, tenemos una función setTimeout() que espera medio segundo antes de crear un elemento y agregarlo al cuerpo del documento. Luego tenemos una función asíncrona llamada foo() que intenta localizar ese elemento (while(!expresión)) y espera una promesa si aún no puede encontrarlo. La promesa simplemente espera una décima de segundo y se resuelve.

La forma en que visualicé que esto funcione es que las primeras cinco veces que se ejecuta el bucle while, el elemento no se encuentra y la promesa se resuelve. Luego, en la sexta vez, la función setTimeout() en la parte superior crea el elemento y la expresión del bucle while se resuelve como verdadera. Esto significa que se alcanza el console.log() dentro de la expresión foo().then() (y el código puede continuar).

Creo que este es un problema de sincronización. Cuando el código que crea el elemento se saca de la función setTimeout(), el código se ejecuta correctamente, por lo que parece que el bucle while se ejecuta indefinidamente antes de que la función setTimeout() superior pueda activarse. ¿Por qué sucede esto? ¿Hay alguna forma de solucionarlo sin reescribir todo el código? Parece que esta función foo(), que tengo en un código más grande, dejó de funcionar recientemente. ¿Cambió algo en la forma en que los navegadores analizan Javascript?

Nota: La idea detrás de foo() es que lo que escribo dentro de la función then() siempre debe esperar a que se cree el elemento identificado por expresión.

setTimeout(function () {
    const el = document.createElement('div')
    el.id = 'bar'
    el.innerText = 'Bar'
    document.body.appendChild(el)
}, 500)

const promise = new Promise(function(resolve) {
    setTimeout(function() {
       resolve()
    }, 100)
})

async function foo(expresión) {
    while(!expresión) {
        await promise
    }
}

foo(document.getElementById('bar')).then(function() {
    console.log(document.getElementById('bar'))
})
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Hay un problema de sincronización en el código donde el bucle while en la función foo() se está ejecutando indefinidamente antes de que la función setTimeout() tenga la oportunidad de crear y agregar el elemento al cuerpo. Esto hace que la expresión foo().then() no se alcance y el código no se ejecute como se pretende.

    Una forma de solucionar esto sería esperar a que el elemento se cree y se agregue al cuerpo antes de llamar a la función foo(). Esto se puede hacer envolviendo la expresión foo().then() en un oyente de evento DOMContentLoaded.

    document.addEventListener('DOMContentLoaded', function() {
        foo(document.getElementById('bar')).then(function() {
            console.log(document.getElementById('bar'))
        })
    });
    

    Esto asegura que la función foo() solo se llama después de que el elemento se haya creado y se haya agregado al cuerpo, permitiendo que el bucle while verifique adecuadamente el elemento y resuelva la promesa.

    Es posible que un cambio reciente en el comportamiento o la sincronización del navegador haya causado la aparición de este problema. Siempre es buena idea probar y actualizar regularmente el código de JavaScript para garantizar la compatibilidad y prevenir problemas imprevistos.

Comments are closed.