He estado trabajando con JS durante aproximadamente un año y todavía estoy aprendiendo. Mi pregunta es al final.
En el primer ejemplo:
console.log('Start'); setTimeout(()=> console.log('inside callback'), 0); console.log('End');salidas
Start End inside callback Entiendo que a pesar de que el tiempo de espera es 0 , todavía tenía que ir al navegador WebApi (setTimeout api) e inmediatamente empujado a la cola de devolución de llamada esperando que el hilo principal esté libre (que actualmente está ejecutando console.log('End')) . Una vez que el hilo está libre, se ejecuta la devolución de llamada y se imprime la "devolución de llamada interna".
Siguiendo este enfoque, traté de experimentarlo con otra WebAPI, es decir, DOM API.
Esta vez, en lugar de setTimeout, usé document.querySelectorAll()
console.log('Start'); console.log(document.querySelectorAll('img')) console.log('End');Salidas
Start NodeList(4) [img.bar-sm.-avatar.js-avatar-me, img.bar-sm.avatar.s-avatar--image, img, img] EndEsta vez vemos la salida de la API DOM antes de que se imprima END.
Conozco el resultado, pero quiero entender el flujo que hay detrás.
¿Por qué no siguió el patrón como setTimeout?
¿Por qué la salida DOM no vino después de "Finalizar" si se procesó en un hilo separado?
¿Siguió el siguiente flujo?
document.querySelectorAll -> webAPI -> cola de devolución de llamada -> hilo principal
¿La API DOM tiene que pasar por la cola de devolución de llamada y esperar a que el hilo principal esté vacío ? ¿Si es así? ¿Cómo es que esta vez tenemos las consolas en el orden correcto a diferencia de setTimeout?
Todavía estoy aprendiendo y agradecería mucho la explicación. Por favor señale cualquier cosa si entendí mal. Gracias.
La razón es que document.querySelectorAll es un método síncrono mientras que setTimeout es asíncrono.
Los scripts JS se ejecutan en el mismo entorno en el que vive el DOM, por lo que no es asíncrono. Los eventos asincrónicos son eventos que generalmente se envían a otro entorno (luego para ser manejados por el bucle de eventos)
Esto es parte del modelo de concurrencia basado en un bucle de eventos, que en realidad es responsable de ejecutar el código, recolectar y procesar el evento. La función setTimeout se llama con 2 argumentos: un mensaje para agregar a la cola de devolución de llamada y un valor de tiempo (opcional; el valor predeterminado es 0). El valor de tiempo representa el retraso (mínimo) después del cual el mensaje se insertará en la cola. Si no hay ningún otro mensaje en la cola y la pila está vacía, el mensaje se procesa inmediatamente después de la demora. Sin embargo, si hay mensajes, el mensaje setTimeout tendrá que esperar a que se procesen otros mensajes y, por este motivo, el segundo argumento indica un tiempo mínimo (no un tiempo garantizado). Por lo tanto, el mensaje 'fin' se escribirá en la consola antes de que se procese el mensaje en la devolución de llamada 'dentro de la devolución de llamada', porque el retraso es el tiempo mínimo requerido para que el tiempo de ejecución procese la solicitud (no es un tiempo garantizado).
document.querySelectorAll es parte de los scripts que se ejecutan en el mismo entorno en el que vive el DOM, por lo que no es asíncrono y se ejecutará de inmediato.
La manipulación de DOM es síncrona. Dicho esto, el proceso de reproducción de la página por parte del navegador en respuesta a una actualización del DOM es asíncrono. Esto puede dar la ilusión de una actualización DOM asíncrona.
Más información sobre el bucle de eventos de JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop