Anuncios

Bienvenidos sean a este post, hoy seguiremos con el asincronismo.

Anuncios
Anuncios

Sabemos que javascript corre en un solo thread pero si usamos las promesas que vimos en el post anterior se encargan de «encolar» todas las llamadas asincronicas en un lugar particular de la memoria para ejecutarlos en otro momento y estas nos aseguran que esa seccion particular del codigo se ejecutan solo cuando se hayan completado las llamadas asincronicas. Pero no debemos olvidar que Javascript seguira ejecutando linea por linea nuestro codigo y esto puede terminar en resultados y/o errores ineseperados.

Anuncios

En ocasiones deberemos hacer una serie de llamadas a funciones asincronicas una detras de la otra. En estos casos lo mas recomendable seria que se pausara hasta que se termine de ejecutar todo el codigo asincronico. Aqui es donde entran las palabras que dan titulo al post, donde async se encarga de preparar todo para que await pause todo hasta que se cumpla la promesa. Para entenderlo vamos a analizar el siguiente ejemplo:

export function promesaDemorada(): Promise<void> {
        return new Promise<void>(
                (
                  resuelto: () => void,
                  rechazo: () => void
                ) => {
                        setTimeout(() => {
                          console.log("2. llamando a resuelto()");
                          resuelto();
                        }, 1000);
                }
        )
}

async function llamarPromesa() {
        console.log("1. antes de llamara promesaDemorada");
        await promesaDemorada();
        console.log("3. despues del llamado");
}

llamarPromesa();
Anuncios

La primera funcion sera una promesa demorada porque devolveremos una promesa, como siempre estableceremos dos funciones para manejar los dos posibles estados, de lo cual hablamos en el post anterior, y en la funcion establecemos una demora mediante setTimeout donde llamaremos a la funcion del estado resuelto. La siguiente funcion es para llamar a la anterior, en esta simplemente tenemos un texto donde indicamos una situacion, llamamos a la funcion anterior, y luego mostramos otro mensaje. Por ultimo hacemos un llamado a la ultima funcion. Con todo esto comentado veamos como es su salida:

Anuncios

Un detalle que no comentamos sobre la segunda funcion es que antepusimos al async. Esto le indicara que es asincronico y el codigo sabra que debe manejarlo asi y siempre las funcionas asincronicas devuelven una promesa. Por otro lado el llamado a la funcion con la promesa posee un await, este es el encargado de detener toda ejecucion hasta que se cumpla o rechace la promesa. Tambien debemos mencionar que los await solamente se pueden usar con funciones asincronicas. Por esta razon cuando llamamos a la funcion esta no se ejecuta hasta terminada la demora y luego recien tenemos la siguiente linea.

Anuncios

Esto que vimos es un ejemplo simple donde todo sale bien pero los errores pueden ocurrir. En el post anterior mencionamos que tenemos a then para manejar los valores devuelto satisfactoriamente por la promesa y catch para los errores. Pero aqui no disponemos de esto, aunque esto no significa que no disponemos de algun metodo para hacerlo. En este caso entran en accion los miticos try/catch tan utilizados en muchos lenguajes para poder realizar esto. Tomemos el codigo anterior y realicemos unas modificaciones:

export function promesaDemorada(): Promise<string> {
        return new Promise<string>(
                (
                  resuelto: (res: string) => void,
                  rechazo: (err: string) => void
                ) => {
                        setTimeout(() => {
                          console.log("2. llamando a rechazo()");
                          rechazo("promesa rechazada");
                        }, 1000);
                }
        )
}

async function llamarPromesa() {
        try {
          console.log("1. antes de llamara promesaDemorada");
          await promesaDemorada();
        } catch(error) {
          console.log("3. await lanzo " + error);
        }
}

llamarPromesa();
Anuncios
Anuncios

Es el mismo codigo anterior pero con sutiles diferencias y esta siempre devolvera un error. La primera modificacion sera que en lugar de devolver una promesa con un void lo hace con un string. Ahora nuestras funciones de callback encargadas de manejar los estados reciben un argumento y en el bloque sigue siendo similar pero en lugar de llamar a resuelto lo hace a rechazo y con un mensaje. La verdadera modificacion esta en la segunda llamada donde agregamos un bloque try/catch. En el try tendremos el codigo anterior donde notificaremos el llamado y el llamado a la funcion anterior. Lo siguiente es un bloque catch que recibira el error, en este caso el mensaje enviado por la funcion rechazo, y en este solo mostraremos un mensaje notificando el fallo y el porque. Pasemos a ver como es su salida:

Anuncios

Como podemos ver el error fue capturado por el bloque catch porque al igual que vimos en el post anterior, el valor de la funcion rechazo siempre representa al estado de promesa rechazada.

Anuncios

Si bien recien vimos como enviar un mensaje para el estado rejected tambien podemos enviar valores mediante la funcion del otro estado. Para ello nuevamente tomaremos el codigo anterior y lo modificaremos de la siguiente manera:

export function promesaDemorada(): Promise<string[]> {
        return new Promise<string[]>(
                (
                  resuelto: (res: string[]) => void,
                  rechazo: (err: string) => void
                ) => {
                        resuelto(["Martin", "Miranda"]);
                }
        )
}

async function llamarPromesa() {
        let valores = await promesaDemorada();
        for(let valor of valores) {
                console.log("Valor: " + valor);
        }
}

llamarPromesa();
Anuncios

En este caso la promesa devolvera un array de tipo string y la funcion que devuelve el estado resuelto tambien recibira este tipo de dato. En el bloque no tenemos mas el setTimeout sino directamente el llamado a la funcion resuelto y le pasamos dos valores. En la funcion primero definiremos una variable que recibira el resultado de la funcion anterior. Luego mediante un bucle pasaremos por todos los valores recibidos en la variable anterior y lo mostraremos en pantalla. Compilemos y veamos su salida:

$ node async.js
Valor: Martin
Valor: Miranda
$
Anuncios

Como pueden ver recibimos los valores enviados por esta funcion. Con esto hemos completado el tema de async y await. Con este tema completamos todas las formas de trabajar con codigo asincronico, ya sea mediante callback del cual hablamos en este post, promesas de las cuales hablamos en este post y aqui completamos con async y await. Todas son herramientas para trabajar de esta forma pero si prestaron atencion hemos usado las tres y en algunas ocasiones al mismo tiempo.

Anuncios

En resumen, hoy hemos visto async y await, que son, para que sirven, como se utiizan, algunas caracteristicas, asi como tambien algunos ejemplos para verlos en accion. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50