Saltar al contenido
Angular Async/Await: Por qué lo necesitabas y cómo usarlo

Angular Async/Await: Por qué lo necesitabas y cómo usarlo

¿Qué es Async Await en Angular y cómo usarlo para evitar el infierno de las devoluciones de llamada? Conozca las respuestas en nuestro último artículo

6min read

Angular es un gran marco, pero escribir código asincrónico y hacer llamadas asincrónicas es difícil. Especialmente si no puede decidir entre Async/Await y Angular Promise. Por lo tanto, en este tutorial, lo ayudaré a comprender las diferencias entre Async/Await y Promise a través de ejemplos y fragmentos de código. También explicaré cómo puede evitar fácilmente el infierno de las devoluciones de llamada y demostraré cómo usar Async/Await en JavaScript con la ayuda de Ignite UI for Angular componentes.

Try Ignite UI for Angular

¿Qué es el código asincrónico en Angular?

Cuando hablamos de código asíncrono, simplemente nos referimos a que el código no se ejecuta secuencialmente y el proceso implica multithreading. Es una forma de programación paralela que ejecuta un bloque de código separado sin interrumpir el subproceso principal de la aplicación. La ejecución de código asincrónico es útil en el caso de iteraciones grandes o cuando se tienen operaciones complejas.

Pero si su objetivo es la simplicidad y las operaciones de ejecución corta para su aplicación Angular, es mejor evitar la programación asincrónica. Por lo general, el código asincrónico es más difícil de leer, por lo que cualquier cosa que pueda mejorar su legibilidad y simplificarlo para los desarrolladores se considera un refuerzo de calidad. Y JavaScript tiene sus propios trucos y mecanismos para hacer frente a esto.

How JavaScript Handles Asynchronous Code

De forma predeterminada, JavaScript es un lenguaje sincrónico de un solo subproceso, que ejecuta una instrucción a la vez de arriba a abajo. Esto significa que los nuevos subprocesos y procesos no pueden ejecutar código en paralelo con el flujo principal del programa. Tiene una pila de llamadas y una memoria de montón y ejecuta el código en orden y debe terminar de ejecutar un fragmento de código antes de pasar al siguiente. Todo sucede secuencialmente. Pero, ¿qué ocurre cuando, por ejemplo, hay que realizar varias llamadas AJAX en una sola página?

La primera solución que me viene a la mente es el uso de devoluciones de llamada. Pero conducen a un problema importante conocido por los programadores como "infierno de devolución de llamada". Básicamente, se trata de una estructura de código anidada que requiere la realización de múltiples solicitudes y transformaciones de datos, lo que a menudo da lugar a un código difícil de mantener y leer, y a una aplicación menos escalable.

Resulta que las devoluciones de llamada no son la mejor manera de manejar el código asincrónico para tu aplicación Angular. ¿Y entonces qué? ¿Quizás Angular promesa? Este patrón ajusta de forma eficaz las operaciones asincrónicas y notifica cuando se completan. Sin embargo, a pesar de que ofrece un código más limpio y fácil de mantener, el uso de Angular Promise no es la solución óptima ya que, a menudo, reutiliza el mismo código una y otra vez, contradiciendo el DRY (Don't Repeat Yourself) principle.cl

Afortunadamente, tenemos Async/Await en Angular.

Using Async/Await in Angular

Una de las mejores mejoras en JavaScript es la función Async/Await introducida en ECMAScript 7. Básicamente, Async/Await funciona sobre Promise y le permite escribir código asincrónico de manera sincrónica. Simplifica el código y hace que el flujo y la lógica sean más comprensibles.

Tenga en cuenta que debido a que ya no usa el encadenamiento then y catch, puede controlar los errores ejecutando try/catch.

Async/Await vs Promise: ¿Cuál es la diferencia?

Para presentar las diferencias entre Async/Await y las promesas, hagamos una tabla para compararlas de una manera más digerible y concisa.

Promise 

Async/Await 

Promise es una operación que está garantizada para completar su ejecución en algún momento en el futuro

Async/Await se basa en promesas. Son azúcar sintáctico para las promesas, lo que hace que el código parezca más sincrónico

El manejo de errores se realiza mediante los métodos .then() y catch()

El manejo de errores se realiza mediante los métodos try() y catch()

A veces puede ser difícil entender las cadenas de promesas

Async y await hacen que el código sea más fácil de leer y comprender el flujo del programa

Tiene 3 estados: pendiente, resuelto y rechazado

Devuelve una promesa resuelta o rechazada

Vamos a crear un ejemplo con ambas sintaxis en una cuadrícula de datos Angular y veamos las diferencias. Tenemos una función que consiste en realizar dos llamadas asíncronas a una API, una para obtener datos de los usuarios y otra para obtener clubes en los que los usuarios son miembros. La segunda llamada depende de la primera, lo que significa que getUserData() debe completarse antes de continuar con la otra solicitud. Ambas sintaxis son fáciles de leer, pero, por supuesto, el uso de promesas con .then() y .catch() puede llevar a un infierno de devolución de llamada, lo que hace que el código sea difícil de entender y mantener.

const makeRequest = () =>
     getUserData()
    . then(user => getClubsForUser(user.id))
    .then(console.log)
    .catch(err => console.log('Error: ' + err.message));
const makeRequest = async () => {
    try {
        let user = await getUserData();
        let clubs = await getClubsForUser(user.id);
        console.log(clubs);
     }
    catch(err) {
        console.log(err.message);
   }
};

 

Cómo usar Async/Await en Angular con Ignite UI

Vamos a crear una función que obtendrá los datos del usuario de la entrada de un formulario y luego hace una solicitud a una api para verificar si las credenciales del usuario son correctas y, si es así, redirige a la página de inicio. El uso de Async/Await en Ignite UI for Angular puede ayudarnos en esta situación. Tenemos una solicitud a una API que es una operación asíncrona y es por eso que usaremos await para ella y luego si no hay otros problemas para guardar los datos.

const submitLoginData = async () => { 
    try { 
         if (this.userInput.email && this.userInput.password) { 
         const response = await this.loginUser(this.userInput); 

         if (response.statusCode === 200) { 
             alert('User is successfully logged in!'); 
             await saveUserData(response.data); 
             this.router.navigate(['/']); 
         } 
         else { 
             alert(response.message); 
             this.router.navigate(['/login']); 
         }
     } 
   } 
     .catch(err) { 
         alert('Something went wrong, try again later!') 
         this.router.navigate(['/login']); 
     } 
} 

Definitivamente podemos usar .then() y .catch() aquí, pero Async/Await en Ignite UI for Angular hace que el código se vea más elegante. Depende de la persona que está escribiendo el código elegir qué sintaxis usar. Pero también, se recomienda ceñirse a un enfoque, ya que mezclar estilos puede complicar el código.

Async/Await Angular Best Practices

Cuando usamos async y await para manejar código asincrónico, siempre debemos poner nuestro código en el bloque try/catch. De esta forma nos aseguraremos de que aunque la promesa esté arrojando un error, esta será detectada y procesada correctamente.

async function loadComponents() {
     try {
         this.components = await fetchComponentsByType('charts');
     }
     .catch(err) {
         logger.error(err);
     }
}

Con Ignite UI, no es necesario devolver explícitamente una promesa en una función asincrónica. De hecho, una función asincrónica siempre devuelve una promesa. Lo que significa que crear una promesa dentro de una función asíncrona solo agrega sobrecarga de rendimiento a nuestra aplicación Angular.

async function loadChartSelectors() {
     return Promise.resolve(['igx-data-chart', 'igx-pie-chart', 'igx-category-chart']);
}

Resumen

Las palabras clave Async/Await hacen que el código sea más fácil de leer y depurar. Sin embargo, si queremos usarlos correctamente, debemos entender cómo funcionan las promesas en general, porque como dijimos no son más que azúcar sintáctico para las promesas.

Ignite UI Angular

Solicitar una demostración