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.

¿Se resuelven las promesas durante la inicialización del módulo antes que los scripts (con await a nivel superior)?

Al utilizar webpack (v5 a través de webpacker v6) y exportar una interfaz (por ejemplo, a través de globales) a otros scripts en una página web, ¿los promises resueltos durante la inicialización del módulo necesariamente se ejecutan antes de que los scripts en la página accedan a ellos? ¿Existe alguna forma de asegurarse de que lo hagan? ¿Funcionaría el await de nivel superior?

Específicamente, imagine que tengo un módulo que se exporta a la biblioteca global FOO que se ve así:

---En el módulo obtenido por webpack---
class Foo { ... }
const done = (async function()  {
    Foo.bar = 10 - (await prom)/(await other_prom)
})()
resolve(5); other_resolve(80); //resuelve para prom/other_prom
await done //si tenemos await de nivel superior
export {Foo}

--- En la etiqueta de script (no procesada) más adelante ---
new FOO.Foo(20); //Esto no debería ejecutarse hasta DESPUÉS de que la función asíncrona haya modificado Foo

Me gustaría que nuevo FOO.Foo(20) estuviera garantizado de no ejecutarse hasta después de que la función asíncrona de arriba termine de ejecutarse. ¿Hay alguna forma de garantizar que esto no se ejecutará antes de que se complete la inicialización, aparte de envolver todo el javascript de la página en una función asíncrona y esperar que se resuelvan todas las promises de inicialización? En ese punto, podría renunciar a las comodidades de asincronía y escribir funciones de callback.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Cuando se exporta una interfaz usando webpack, las promesas resueltas durante la inicialización del módulo pueden no necesariamente ejecutarse antes de que los scripts en la página web accedan a ellas. En el ejemplo dado, la sentencia new FOO.Foo(20) puede ejecutarse antes de que la función asíncrona modifique Foo.

    Para asegurarse de que new FOO.Foo(20) se ejecute solo después de que la función asíncrona haya modificado a Foo, una forma es usar el await de nivel superior. Con await de nivel superior, la sentencia await done hará que el módulo espere a que la función asíncrona complete antes de exportar la interfaz Foo a la Biblioteca global.

    --- En el módulo que se va a empaquetar ---
    class Foo{...}
    const done = (async function()  {
        Foo.bar = 10 - (await prom)/(await other_prom)
    })()
    resolve(5); other_resolve(80); //resolve para prom/other_prom
    await done //si usamos el await de nivel superior
    export {Foo}
    
    --- En la etiqueta de script (no procesado) posterior ---
    await import('./module.js'); //si usamos el await de nivel superior aquí
    new FOO.Foo(20);  //Esto se ejecutará solo después de que la función async haya modificado a Foo
    

    Tenga en cuenta que para que el await de nivel superior funcione, el módulo que contiene la sentencia export debe importarse mediante la sentencia import con la palabra clave await. Esto asegurará que el módulo esté completamente iniciado antes de ejecutar los códigos siguientes.

    Si no se utiliza el await de nivel superior, entonces todo el código que necesita esperar a que se complete la inicialización del módulo deberá envolverse en una función asíncrona y esperar a que se resuelvan todas las promesas.

Comments are closed.