Saltar al contenido

Async/Await en Javascript: todo lo que necesitas saber

junio 21, 2021

Cuando programamos aplicaciones de todo tipo, pero especialmente en la web, necesitamos con frecuencia consumir recursos que se encuentran en bases de datos o en otros servidores y estos recursos no se cargan inmediatamente. Es por esta razón que tenemos que solicitarlos y realizar espera hasta que los tengamos completamente cargados y usarlos.

Javascript ha ido evolucionando con el paso de los años y poco a poco ha ido transformándose y teniendo nuevas forma de implementación y capacidades. Los famosos callbacks y las Promises vinieron a darnos muchas capacidades, sin embargo no son un comportamiento 100% síncrono.

Para lograr un comportamiento síncrono la mejor opción es usar el async/await ya que esto nos permite continuar ejecutando código mientras realizamos peticiones en segundo plano y al completarse la petición realiza la acción solicitada. También detecta correctamente si hay un error o una excepción.

Por qué usar Async/Await

Para poder entender mejor la razón por la que debes aprender a utilizar correctamente el Async/Await vamos a analizar sus funciones antecesoras, así vamos a conocer las ventajas en relaciones a ellas. Como ya lo mencioné, estamos hablando de los Callbacks y las Promises.

Callback (llamadas de retorno)

Si alguna vez has programado en Javascript, estoy más que seguro que has usado un Callback. Básicamente consiste en una función que al completarse llama a otra función. De esta manera como programador puedes hacer que una función sea llamada en el momento que especifiques. Sin embargo, esto tiene varios problemas, especialmente con el rendimiento y sobre todo con la legibilidad del código.

Cuando usamos Callback para realizar algunas operaciones en orden, pronto vamos a caer en lo que conocemos como «Infierno de Callback». Esto ocurre cuando tienes demasiados callbacks anidados dentro de una función. Se vuelve muy complicado saber en qué momento se ejecutará cada función o detectar un posible error. El Infierno de callbacks luce más o menos así:

asyncCallOne( () => {
  asyncCallTwo( () => {
    asyncCallThree( () => {
      asyncCallFour( () => {
        asyncCallFive( () => {
          asyncCallSix( () => {
            asyncCallSeven( () => {
              asyncCallEight( () => {
                 asyncCallNine( () => {
                    asyncCallTen( () => {
                     //do something here
                    })
                  })
                })
              })
            })
          })
        })
      })
   })
})    

Es un verdadero dolor de cabeza trabajar con este tipo de funciones, especialmente cuando se ejecutan callbacks a nivel complejo. Es un panorama complicado incluso para el programador que escribe el código, imagina para el equipo de trabajo.

Promises (promesas)

La estructura de una promesa es mucho más parecido a un sistema asíncrono, sin embargo no completa su funcionamiento. En una promesa asignamos la Promise a una variable y luego a esta variable podemos llamar el método .then( ) que se ejecutará si la Promise se resuelve correctamente o el método .catch( ) que se ejecutará si algo sale mal.

La mejor forma de entenderlo es con un ejemplo. Tengo que aclarar que cualquier sistema asíncrono puede realizarse con promesas, el problema suele ser el mismo, pronto vamos a caer en un infierno de Promises. Con una gran cantidad de .then( ) consecutivos. Veamos como funcionan:

const promiseFunction = new Promise((resolve, reject) => {
  const add = (a, b) => a + b;
  resolve(add(2, 2));
});

promiseFunction.then((response) => {
  console.log(response);
}).catch((error) => {
  console.log(error);
});

Si bien es cierto que las promesas representaron un increíble avance en el mundo del desarrollo web con Javascript, la asincronía fue posible ya que al ejecutarse la función la espera se realiza y al terminar se ejecuta el .then( ) lo que es sencillo y puede ser predictivo. Sin embargo para realizar procesos asíncrono lo mejor es usar Async/Await

Funcionamiento del Async/Await

Una función asíncrona tiene la capacidad de realizar esperas a que los datos se procesen, pero tiene la peculiaridad de que no está sujeta a realizar una sola espera, en resumen, ese es el poder de esta función. Podemos realizar las funciones en un entorno global y llamarla de forma ordenada, a función asíncrona va a ejecutarlas en el orden y podremos ver claramente el proceso dentro de la función. Veamos un ejemplo.

const asyncFunction = async () => {
  // Code
  await functionAsync01();
  await functionAsync02();
}


const functionAsync01 = async () => {
  //code
}


const functionAsync02 = async () => {
  //code
}

De esta forma podemos realizar las llamadas que queramos con sus respectivas esperas y todo en la misma función trabajando cada llamada por aparte en el sistema. Eso facilita mucho la lectura y hace que no caigamos en ningún infierno. Es solo una función que dentro de su código llama otras.

La palabra Await es la que le dice al sistema que realice la espera, pero hay que tener en cuenta que esta solo se puede usar cuando la función que llamamos con ella es una función asíncrono también. Y por supuesto, el Await solo puede usarse dentro de una función asíncrona.

Consideraciones a tener en cuenta

Cuando realizar una función asíncrona normalmente la asignamos a una constante, la forma de llamar a esta función asíncrona es muy similar a llamar a una promesa, utilizando el .then( ) podemos capturar el valor que devuelva la función, y con el .catch( ) capturamos un posible error. Ten en cuenta que el catch se lanzará si cualquier de las funciones internas lanzan un error. Así que tendrás que depurar internamente para saber cual es la función que está provocando la falla.

Hay mucho más que contar respecto a las funciones asíncronas y las esperas. Puedes asignar valores predeterminados o realizar comparaciones para ver cual función devuelva valores antes para saber que servidor consultar, etc. Pero son usos más específicos que se salen del objetivo de este artículo.

Espero que la información te hay gustado, pero especialmente espero que te hay servido. Nos vemos en el siguiente artículo. Hasta pronto.