Mientras miraba este código:
<script> console.log(1); new Promise(r=>r()).then(() => console.log(2)); </script><script> console.log(3); </script>parece que 2 debería imprimirse después de 3, porque debería haberse puesto en cola como una microtarea, tal como se comporta aquí:
<script> console.log(1); new Promise(r=>r()).then(() => console.log(2)); console.log(3); </script>No puedo encontrar una buena explicación: ¿por qué el motor JS se molestaría en vaciar la cola de microtareas antes de continuar procesando el siguiente elemento del script?
No es el motor JS sino el DOM, que después de ejecutar un script clásico tiene que limpiarse después de ejecutar un script (paso 8). Este algoritmo de limpieza realiza un punto de control de microtareas.
- Si la pila de contexto de ejecución de JavaScript ahora está vacía, realice un punto de control de microtarea .
Por lo tanto, la microtarea realmente no se verifica "antes" de la etiqueta final </script> , sino justo después de que se ejecuta el script (lo que técnicamente sucede cuando se cumple la etiqueta final).
Incluso puede hacer algunas cosas divertidas como obligar a un MutationObserver a notificar los cambios en el DOM justo en el medio del análisis del contenido de un elemento. Esto puede ser útil para las pruebas. :
<script> function myObserver(mutationsList) { for (let mutation of mutationsList) { for (let n of mutation.addedNodes) { if (n.id === 'parent') { console.log("innerHTML: ", n.innerHTML); } } } } var observer = new MutationObserver(myObserver); observer.observe(document.body, { childList: true, subtree: true }); </script> <div id="parent"> <span>This will be parsed</span> <script>/* This script forces the MutationObserver to kick its notifications */</script> <span>Not yet parsed</span> </div>