Vamos a sincronizarnos un poco

Imagen de natanaelginting.

O dicho de otro modo, vamos a ver las diferencias entre sincronía y asincronía en Javascript, ya que a veces puede resultar confuso.

Sincronía

Podríamos pensar que cuando hay callbacks, es que existe asincronía, porque parece que esperamos la ejecución de algo que no sabemos cuándo se va a ejecutar. Sin embargo, el hecho de que exista un callback no implica necesariamente que sea asíncrono. Vamos a ver un ejemplo en el que, a pesar de tener callbacks, todo es síncrono.

Esquema hecho por Carlos Ble

Nos podemos imaginar el recorrido de las funciones como si una aguja, que va pasando por todos los puntos y sube y baja, según sea el caso. Nuestra aguja en este ejemplo empieza en la línea 1, en la que se empieza a definir la función llamada “it”, así pues, su siguiente paso será saber qué hay dentro, así que salta a la línea 19 en la que it se ejecuta, y así sucesivamente (se puede seguir el flujo con los números de color negro que hay en la imagen).

Este caso, como hemos indicado más arriba, es síncrono, pues sólo existe una aguja, aunque ésta esté saltando de arriba a abajo continuamente. Es decir, sólo hay un flujo de ejecución.

¿Cuándo es asíncrono?

Cuando hay varias agujas, es decir, varios flujos de ejecución, cuyo camino es diferente entre sí.

Aquí vamos a requerir también de los callbacks o bien de promesas, para manejar la asincronía, pero como dijimos antes, no por el hecho de que en tu código haya callbacks, significa que haya asincronía.

Ejemplos de asincronía

  • Por ejemplo, un ejemplo de asincronía es cuando usamos setInterval() o setTimeout(), en los que hay un flujo que se ejecuta cuando pasa determinado tiempo, con lo cual, está separado del flujo principal de la aplicación.
  • Otro ejemplo de asincronía sería cuando realizamos peticiones a un servidor. Vamos a ver en el próximo artículo la más básica, AJAX.

Para ponernos en contexto en el tema que nos atañe ahora, cada vez que lanzo una petición a un servidor, en realidad lo que estoy haciendo es esperar una respuesta que llegará en cualquier momento, pero mi ejecución normal de la página en el navegador no se interrumpe, sino que se crean flujos separados, uno el principal y otro el que gestionará lo que hará con esa respuesta cuando le venga. Por eso, aquí sí que se crea asincronía.

Formas de manejar la asincronía

1) Con un callback

Vamos a poner el ejemplo de un setTimeout().

Como podemos observar, se trata de un test de una aplicación, en este supuesto concreto estamos ejecutando varias funciones que lanzan un juego de preguntas y respuestas con un temporizador, y aquí queremos comprobar que, cuando pulsamos un botón, se reinicia dicho temporizador. Teníamos el problema de que justo al pulsar el botón, aún no se habían reiniciado los segundos, con lo que nuestro resultado no era el esperado, porque no le había dado tiempo de cambiar.

Una posible solución a este problema fue que ejecutara nuestro expect después de un segundo, por eso se puede observar que se ha aplicado un setTimeout() para ello.

Ahora bien, ¿cómo le digo a mi test que se tiene que esperar a que pase ese tiempo para ejecutar el expect?, pues a través de un callback que le pasamos como argumento y que en este caso hemos denominado “done” y que vamos a llamar cuando de verdad hayamos terminado de hacer lo que queremos, en nuestro caso lo que queríamos es que nos hiciera el expect dentro del setTimeout.

2) Async — await

Hay otra manera de gestionar la asincronía, que es con los métodos async-await. Estos métodos muestran de una manera muy visual lo que hemos hecho en el ejemplo anterior, es decir, que espere a realizar determinada acción para darnos el valor.

La función async sería la función asíncrona. Normalmente la llamada a esta función recibe la resolución de un elemento Promise, o sea, una promesa. Cuando async contiene un elemento await, lo que hace éste es esperarse, es decir, pausa la ejecución de async hasta que reciba la resolución de la promesa.

Ejemplo de MDN.

Vemos que lo que hemos conseguido con await es que se espere y resuelva mi promesa en dos ocasiones, con lo que me da dos resultados (20 y 30) y al final ya usa todos esos valores para darme el resultado final.

Concurrencia y asincronía

Cuando se habla de asincronía, hay otra sictuación que se puede dar y es la concurrencia: dos flujos de ejecución que se están ejecutando al mismo tiempo, paralelamente. En este sentido,

  • Si es concurrente, es también asíncrono. Dos flujos de ejecución que se están ejecutando al mismo tiempo, paralelamente.
  • Pero si es asíncrono, no tienen por qué ser concurrente.

Es importante aprender a manejar lo que se conoce como condiciones de carrera, que ocurre cuando varios flujos se pelean por los mismo datos a la vez y, que, si no lo tenemos en cuenta y no manejamos la asincronía, quizás cuando recuperes los datos no son los que tú quieres.

If something does not work, ACT. Yes, you! That’s why I’m now #Developer at @vmware . Formerly @kairos_ds .Constantly absorbing knowledge. Proud #Adalaber

If something does not work, ACT. Yes, you! That’s why I’m now #Developer at @vmware . Formerly @kairos_ds .Constantly absorbing knowledge. Proud #Adalaber