El ciclo de ejecución de Javascript, porque no todo en la vida es Angular ;) - El Mundo de Angular

El ciclo de ejecución de Javascript, porque no todo en la vida es Angular ;)

Angular se sostiene gracias a Javascript es por eso que mientras mas conozcamos de éste, más entenderemos cómo funciona Angular. Uno de los puntos interesantes de cómo funciona Javascript es la forma (y el orden) en que se ejecuta el código que escribamos, ¿por qué? porque si no sabemos en qué «orden» se ejecuta nuestro código podemos agregar «bugs» muy difíciles de detectar y perderíamos mucho tiempo y energía intentando resolverlos. Si no sabemos en qué orden pasan las cosas en nuestro código, si no sabemos las «reglas» de JavaScript, tu programa puede que no se comporte como vos quieras, puede que agregues bugs que ni sabías que existían, y que serán más difíciles de detectar mientras más crezca tu aplicación.

Entender cómo funciona la ejecución del código te da mas confianza, ya que algunas cosas que creías que ocurrían «como por arte de magia” adquieren sentido, y vos te volvés mas confiado en tu trabajo y más feliz también. Ganás tiempo mejorando tu código y lo perdés arreglando bugs, tiempo que podes aprovechar para pasear por la playa o mirar series :P.

 

 

¡Motores JavaScript (enciendan sus motores)!

Primero lo primero, ¿quién ejecuta el código JavaScript? un motor de JavaScript, todos los Browsers traen su propia implementación que debe respetar el estándar que define la EcmaScript. Y está bueno que haya un estándar ya que, si no, cualquier browser haría lo que se le cante y páginas que funcionan en un browser con una implementación de un motor JavaSript,  no funcionarían en otro browser con otra implementación. Es por eso que eso se respeta y es importante que así sea.

Y… ¿cómo está compuesto un Motor de Javascript?

A grandes rasgos, un motor está compuesto de una pila (Stack), un (Heap) y una cola de eventos (Queue).

 

Stack (pila)

Una pila es una estructura de datos en donde el último dato que entra es el primero que sale. Imagináte esos juegos de bebés donde hay un palito y vas «apilando» bloques de madera, para sacar el bloque de abajo de todo, tenés que sacar el que está arriba primero, y así sucesivamente hasta llegar al último. O sea, tenés que sacar el elemento que pusiste último para sacar el siguiente. En muchos lados lo vas ver por sus siglas en ingles LIFO (Last In, First Of) o «el último en entrar es el primero en salir».

Bien la Stack (o pila) en el motor de JavaScript funciona de forma similar, pero en lugar de apilar bloques de madera, apilás «Frames«. Un Frame es la «información» necesaria para ejecutar una función de Javascript. En esa «información» está la función a ejecutar, los argumentos de esa función y las variables locales de la función.

 

Por ejemplo, en la función:

function a( x ) {

console.log(x)

}

 

function b( y ) {

console.log(y)

a('mundo!')

}

 

b('hola')

 

 

  1. Cuando se ejecuta la función «b» un primer Frame se crea, éste contiene la función «b» con sus argumentos y variables locales
  2. cuando la función «b» llama a la función «a», se crea un segundo Frame (con la función «a» sus argumentos y variables locales)
  3. cuando la función «a» termina de ejecutarse (el último Frame de la pila), se lo saca de la pila
  4. cuando la función «b» termina de ejecutarse se lo saca de la Pila (Stack) y la Pila queda vacía.

 

HEAP

Es la estructura en memoria, dentro del motor de Javascript, donde se van guardando los objetos que se van creando. Cuando tenés el siguiente código:

var a = 1

var b = 'hola mundo'

var c = {

'nombre': 'Valeria'

}

 

Las tres variables a, b y c se guardan en el HEAP para acceder cuando se necesiten.

 

Cola(Queue) o Cola de mensajes

Así como está la Pila, como estructura de datos, existe también la Cola. La característica de la cola es que el primero que llega a la cola es el primero en ser atendido. Pensálo como la cola de un banco, en donde la primera persona que llega a la fila (si nadie hace trampa y se cuela) es la primera persona en ser atendida. También se la conoce como FIFO por sus siglas en ingles (First in, First Out), «el primero que entra es el primero que sale»

Volvamos a la Queue  (o cola) de mensajes en nuestro motor de JavaScript, en esa Queue se guardan mensajes a ser procesados. Un mensaje puede ser generado por alguno de los siguientes Eventos:

  • Eventos del browser: por ejemplo, clicks en un botón, teclear en el teclado, scrollear con la ruedita del mouse, etc.
  • XHR: buscar un dato en un servidor remoto, por ejemplo un servicio REST.
  • Timers: setTimeout(), setInterval()

Y todos estos eventos tienen la característica de ser asincrónicos.  Un mensaje asincrónico es un mensaje que se ejecuta en otro momento diferente al actual, o dicho de otra forma, es un código que se ejecuta «más tarde». Es muy importante entender la diferencia entre los mensajes Asincrónicos y los Sincrónicos, ya que el entenderlos te dará la pauta de cuál es el orden de ejecución de tu código.

Bien, esos son los componentes principales de un motor de JavaScript. Ahora vamos a ver cómo cazzo se ejecutan esos mensajes asincrónicos que se ejecutan «más tarde», ya que en algún momento se tienen que ejecutar, ¿no?.

Loop de Eventos

¡Perfecto! ahora que ya sabes lo que es un motor de JavaScript, esto va a ser una papa. Pero primero lo primero, el Loop de Eventos es el mecanismo del motor de JavaScript encargado de manejar y ejecutar los mensajes (esos mensajes asincrónicos que se ejecutan «más tarde»). Y básicamente lo que hace es tomar el primer elemento de la cola de mensajes, ejecutarlo y quedarse esperando a que llegue un mensaje nuevo, si es que no hay ninguno.

 

¡Ejecutarse o morir!

Bueno no tanto como morir, pero una de las características de la ejecución de esos mensajes es que una vez que se tomó un mensaje para ser procesado, éste es ejecutado hasta su totalidad. Sí sí, aunque el mensaje tarde muuuuchoo, es por eso que muchas veces nuestro browser se queda congelado y no nos responde, porque cuando queremos hacer otra cosa como por ejemplo apretar la tecla F5 para refrescar nuestro browser (otro mensaje) éste no se ejecuta ya que queda en lista de espera (en la cola de mensajes), y sólo será procesado cuando el mensaje anterior finalice y el proceso de Loop de Eventos tome el siguiente mensaje. El navegador mitiga esto con el mensaje «un script está tomando mucho tiempo en ejecutarse».

Esto puede traernos ventajas a la hora de programar ya que, si un mensaje es ejecutado en su totalidad, esto nos asegura que ningún otro mensaje va a modificar nuestros datos. Esto es muy distinto en otros lenguajes como Java donde nuestro código (y sus datos) pueden ser ejecutados en dos hilos distintos y tendríamos que «manejar» esa situación y si no tenemos cuidado la información que compartan estos dos hilos podría quedar «sucia».

Una buena práctica es hacer que los mensajes sean cortos para que no se nos congele el browser, el usuario se canse y lo termine cerrando.

 

Añadiendo Mensajes

En los navegadores, cada vez que ocurre un evento, se agrega un mensaje a la cola de mensajes (para su posterior ejecución). Para cada evento (click con el mouse, teclear algo en el teclado, hacer scroll con la ruedita del mouse, etc) hay un «escuchador de eventos». Este escuchador de eventos, cuando ocurre un evento, agrega el mensaje correspondiente a la cola de mensajes. Si no hubiera un escuchador para un evento, este se perdería.

Al llamar a la función setTimeout, recordemos que esta función lo que hace es ejecutar un pedazo de código luego de esperar un tiempo «x» que le indiquemos; lo que su escuchador de mensaje hace es agregar su mensaje correspondiente luego del tiempo indicado «x». Esto es importante ya que lo único que se hace es agregar el mensaje a la cola de mensajes, PERO no ejecutarlo, SOLO agregarlo a la cola, y si hay otros mensajes antes de éste, tendrá que esperar. Es por eso que el tiempo que se le indica a la función setTimeout, es el MÍNIMO tiempo esperado pero no es una garantía de que sea ejecutado exactamente en ese tiempo.

 

 NUNCA TE INTERRUMPEN

Algo interesante que ocurre con este modelo de ejecución de mensajes, o Loop de Eventos,  es que JavaScript nunca interrumpe programas en ejecución. Al usar el mecanismo de «ejecuto lo que esté ejecutando y cuando termino chequeo la cola de eventos» tu código se ejecuta hasta el final y es por eso que hay que tener cuidado de no hacer que tu código haga que se congele el browser (sisi no me voy a cansar de repetir eso, pero esa es la diferencia entre una buena experiencia y una mala experiencia para el usuario).

Si, por ejemplo, tu aplicación tiene que esperar la respuesta de un servidor remoto (por ejemplo un servicio REST) lo que se hace es generar un evento XHR y definir el «código cuando te respondan». Internamente el manejador de eventos (en este caso es un evento XHR) se va a quedar esperando la respuesta del servidor y cuando le respondan va a agregar la respuesta en la cola de mensajes para su posterior procesamiento (cuando llegue su turno).

Acá les dejo un ejemplo -quitando las complejidad de hacer una petición http, la idea es exactamente la misma que con la función setTimeout()-.

 

CONCLUSIONES

Como verán, entender cómo funciona Javascript, más particularmente el motor de JavaScript y el Loop de Eventos, nos ayuda a mejorar mucho cómo funcionan las cosas en Angular. Entender cómo funcionan y procesan los mensajes nos ayuda a entender el orden en el que se ejecuta nuestro código en JavaScript y en Angular también. De ahora en más, cuando veas tu código y no entiendas el orden en el que se ejecutan las cosas, tené en cuenta cómo funciona el Loop de Eventos y cómo se manejan los Mensajes. Y ahora sí… ¡basta de Javascript y volvamos a Angular!

Seguinos en Facebook, Twitter o déjanos un comentario si te gusto el post

About the Author

Mi nombre es Gustavo Hernán Dohara, soy Ingeniero en Sistemas y, sobre todas las cosas, soy un apasionado por la tecnología; tengo más de 10 años de experiencia en diferentes tecnologías y he decidido compartir mis conocimientos y experiencias con cualquiera que desee aprender: alumnos, empleados, freelancers y vos. Al ritmo que cada uno pueda, en el horario en que cada uno pueda y en el lugar que cada uno elija.

 ¡OFERTA! 

 101 Preguntas Sobre javascript

Que te Harán En Cualquier Entrevista (Con Sus Respuestas)