Este es un fragmento de un archivo de prueba de unidad que usa jest. La función de análisis devuelve una Promesa después de que se completa el análisis... Pero no puedo entender el uso de ese indicador booleano (completedAsyncDummyTask).
it("parse is a promise that resolves with parser output", async () => { const parser = new Parser(); let completedAsyncDummyTask = false; setTimeout(() => { completedAsyncDummyTask = true; }, 0); ... const test = await parser.parse(path.resolve(__dirname, "file.xyz")); expect(completedAsyncDummyTask).toBe(true); ... });
¿Algunas ideas?
Gracias por adelantado.
No puedo imaginar cuál sería el propósito de la prueba. Puedo decirte lo que está haciendo, pero no por qué.
Está comprobando que el proceso de parser.parse(path.resolve(__dirname, "file.xyz"))
cumplió su promesa al permitir al menos un bucle a través de la cola de tareas principal ("macro"), no solo haciendo todo su trabajo dentro de la cola de microtareas utilizada por el cumplimiento de la promesa.
Si una promesa se cumple de inmediato, la cola de tareas principal nunca tiene la oportunidad de ejecutarse antes de que se ejecute el código que usa await
:
(async () => { setTimeout(() => { console.log("This comes second because it queues a macrotask"); }, 0); await Promise.resolve(); console.log("This comes first because the promise fulfillment never allowed the macro task queue to be processed."); })();
Pero si no es así, la cola de tareas principal puede procesarse al menos una vez, lo que le da a la devolución de llamada del temporizador la oportunidad de establecer la variable.
La presencia de la prueba sugiere que hay algún código en la aplicación que se basa en ese comportamiento, lo que sería bastante extraño. Aún más extraño que no haya ningún comentario que explique una prueba tan oscura.
Puede sentirse tentado a pensar que, dado que Promise.resolve
devuelve una promesa cumplida, await
no hace nada en absoluto y ese código solo se ejecuta de forma sincrónica. Eso no es cierto, incluso esperar una promesa cumplida implica retrasar el código posterior al menos hasta que la cola de microtareas haya terminado, como podemos ver aquí:
let run = true; let ticks = 0; (async () => { while (run) { await Promise.resolve(); ++ticks; } })(); (async () => { setTimeout(() => { console.log(`This comes second because it queues a macrotask`); }, 0); console.log(`Before: ticks = ${ticks}`); await Promise.resolve(); console.log(`After: ticks = ${ticks}`); console.log("This comes first because the promise fulfillment never allowed the macro task queue to be processed."); run = false; })();