En estos últimos capítulos estamos viendo como funciona la asincronía en Javascript, empezamos manejando los temporizadores, la teoría de la sincronía y dos mecanismos que tiene Javascript para el manejo de la misma como son las callbacks, donde aún no tenemos un manejo apropiado de los errores, y que nos genera la denominada Callback hell, y las promesas, que son una evolución a las callbacks, y además nos permiten tener un código más elegante y ordenado, y nos permite manejar en cualquier petición concatenada que tengamos nos permite manejar el error.
En este capítulo veremos una nueva herramienta que son las funciones asíncronas, que, justamente como su nombre dice, van a esperar a que algo se cumpla para poder seguir ejecutando el proceso que estemos trabajando en ese momento. Las funciones asíncronas no vienen a reemplazar a las promesas, al contrario, trabajan en conjunto. Las funciones asíncronas, sabremos que son tales, porque delante de la palabra function encontraremos la palabra reservada async.
Veamos la sintaxis de las funciones asíncronas.
Ejm
async function funcionAsincronaDeclarada() { }
Para el manejo de errores lo que nos conviene es trabajar un bloque try… catch. En el try se incluye el código en el que vamos a estar trabajando.
Al trabajar con funciones asíncronas, cada petición la puedo guardar en una variable y estar evitando hacer uso de then() indiscriminado, que es lo que algunos puristas denominan el Promise Hell.
Ejm
function cuadradoPromise(value) { if(typeofvalue !== "number") return Promise.reject (`El valor ${value} no es un número`) return new Promise((resolve, reject) => { setTimeout(() => { resolve({ value, result:value * value, }) }, 1000); }) } async function funcionAsincronaDeclarada() { try { console.log("Inicio Async Function"); let obj = cuadradoPromise(0); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = cuadradoPromise(1); console.log(`Async Function: ${obj.value} - ${obj.result}`); } catch (error) { } }
El código de arriba no va a funcionar, ya que la clave es que cuando declaramos una función como asíncrona, hay una palabra reservada denominada await, que le dice a Javascript dentro de una función asíncrona que espere el resultado de esta ejecución antes de pasar a la siguiente linea y ejecutarla.
Por lo que la sintaxis de nuestra función asíncrona sería la siguiente.
Ejm
async function funcionAsincronaDeclarada() { try { console.log("Inicio Async Function"); let obj = await cuadradoPromise(0); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = await cuadradoPromise(1); console.log(`Async Function: ${obj.value} - ${obj.result}`); } catch (error) { console.log(error); } } funcionAsincronaDeclarada();
Este mecanismo nos evita tener concatenados varios then(), con lo que hasta cierto punto nuestro código será mas legible.
Es por ello que decimos que las funciones asíncronas no vienen a reemplazar a las promesas, trabajan con ellas, nos evitan tener que utilizar demasiados then(), facilitando el código y haciéndolo mas legible.
Funciones asíncronas expresadas
Hasta ahora hemos creado funciones asícronas declaradas, en los siguientes párrafos vamos a crear funciones asíncronas expresadas.
Ejm
// Función asíncrona expressada const functionAsincronaExpresada = async () => { try { console.log("Inicio Async Function Expresada"); let obj = await cuadradoPromise(0); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = await cuadradoPromise(1); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = await cuadradoPromise(2); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = await cuadradoPromise(3); console.log(`Async Function: ${obj.value} - ${obj.result}`); obj = await cuadradoPromise(4); console.log(`Async Function: ${obj.value} - ${obj.result}`); console.log("Fin Async Function") } catch (error) { console.log(error); } } functionAsincronaExpresada();
Como podemos ver, tanto la función asíncrona declarada como la expresada están consumiendo una promesa.