Contenido del curso

Manipulando Elementos del DOM

Cómo JavaScript ejecuta código asíncrono

Resumen

Si alguna vez te preguntaste por qué JavaScript a veces ejecuta tu código en orden y otras veces parece saltarse líneas, la respuesta está en cómo funciona el motor de JavaScript en el navegador. Aquí te explico cómo opera la programación síncrona y asíncrona en JavaScript, y por qué entender el call stack y las web APIs cambia la forma en que escribes tu código.

¿Cómo funciona el motor de JavaScript en el navegador?

El JavaScript Engine se apoya en dos piezas que trabajan juntas para ejecutar tu programa: el memory heap y el call stack.

El memory heap es el espacio donde se guardan, de forma aleatoria, todas las variables, funciones y objetos que creas. Piensa en él como un almacén sin orden estricto, pero accesible.

El call stack es la pila donde se apilan las funciones que deben ejecutarse, una sobre otra. Si tienes una función Hola mundo que llama a otra llamada Mi nombre es Diego, el call stack ejecuta primero la de arriba y baja resolviendo en orden [00:35].

¿Qué es el call stack en JavaScript? Es la pila donde se registran y ejecutan las funciones de tu programa, una a la vez, en el orden en que se llaman.

¿Qué significa que JavaScript sea síncrono por defecto?

JavaScript trabaja una tarea a la vez. Esa es la esencia de la programación síncrona: cada función espera a que la anterior termine antes de ejecutarse. Todo ocurre dentro del call stack, en fila india.

Esto tiene una consecuencia famosa entre desarrolladores: el stack overflow. Cuando apilas tantas tareas que excedes la memoria permitida, el navegador colapsa, crashea y te toca cerrarlo para liberar memoria [01:30]. Sí, ese es el origen del nombre del sitio que tantas veces te ha salvado.

¿Cómo logra JavaScript ejecutar tareas de forma asíncrona?

Aquí viene lo interesante. Aunque JavaScript es síncrono por naturaleza, el navegador le presta herramientas para simular ejecución en paralelo. La clave son las web APIs, el queue y el event loop.

Cuando llamas a una función que es una web API, esta sale del call stack y se ejecuta en la sección de web APIs mientras el call stack sigue procesando lo que tenga pendiente. Cuando la web API termina su trabajo, lo deposita en el queue, una especie de sala de espera [02:30].

El event loop es el coordinador. Le pregunta constantemente al call stack: ¿ya estás vacío? Si la respuesta es sí, toma lo que está en el queue y lo regresa al call stack para que termine de ejecutarse. Si no, espera.

¿Qué hace el event loop? Vigila si el call stack está libre y, cuando lo está, mueve las tareas en espera del queue de regreso al call stack para ejecutarlas.

¿Cómo se ejecuta un código asíncrono paso a paso?

Mira este flujo con tres funciones: bar, foo y baz. La función bar imprime 1, luego llama a setTimeout, que es una web API que vuelve asíncrono el código [03:10].

  • bar imprime 1 directamente desde el call stack.
  • setTimeout envía un console.log con 2 a la sección de web APIs y luego al queue.
  • baz se ejecuta e imprime 3.
  • Cuando el call stack queda vacío, el event loop sube el 2 desde el queue y lo imprime.

El orden final de impresión es: 1, 3, 2. El 1 y el 2 parecían trabajar en paralelo, pero el 2 solo llegó al call stack cuando este quedó libre.

¿Cómo escribes código asíncrono en JavaScript?

Para aprovechar este comportamiento sin depender solo de setTimeout, usas dos herramientas principales: promesas y async/await.

Las promesas representan un valor que llegará en el futuro: puede resolverse con éxito o fallar. async/await es una sintaxis más limpia para trabajar con esas promesas, haciendo que el código asíncrono se lea casi como si fuera síncrono.

javascript function bar() { console.log(1); setTimeout(() => console.log(2), 0); baz(); }

function baz() { console.log(3); }

bar(); // Imprime: 1, 3, 2

Entender este flujo te da control sobre tareas como peticiones a una API, lectura de archivos o temporizadores, donde no puedes detener todo tu programa esperando una respuesta.

¿Ya sabes en qué proyecto vas a aplicar promesas o async/await? Cuéntame en los comentarios cómo planeas estructurar tu próximo flujo asíncrono.