Async/await Como Funcionan Realmente: Un Ejemplo

by admin Date: 22-02-2019 async await promises callbacks javascript tutorial


Las Promises nos dan una manera más fácil de tratar secuencialmente la asincronía en nuestro código. Esta es una adición bienvenida, dado que nuestros cerebros no están diseñados para tratar eficientemente la asincronía. Las funciones Async/await, nos ayudan a escribir código completamente síncrono mientras realizamos tareas asíncronas en segundo plano.

La funcionalidad conseguida con las funciones asíncronas se puede recrear combinando promises con generators, pero las funciones asíncronas nos dan lo que necesitamos sin ningún código adicional del boilerplate.

Lo que veremos en este post

  1. Introducción (callbacks, promises, async/await)
  2. Ejemplos: Conversor de divisas que recibe datos asíncronos de dos API's. En este tutorial, vamos a construir una aplicación simple y útil que va a mejorar su conocimiento general de Async/Await.

Empezamos

Una nueva forma de escribir código asíncrono es Async/Await está basado en promises, así que no está bloqueando el flujo.

La gran diferencia es que el código asíncrono se parece y se comporta un poco más al código síncrono. Aquí es donde reside todo su poder.

Las opciones anteriores para el código asíncrono eran callbacks (llamadas de retorno) y promises.

Callbacks en acción

setTimeout(() => {
  console.log('This runs after 1000 milliseconds.');
}, 1000);

Problemas con callbacks El infame infierno de la devolución de llamada

Las llamadas de retorno de anidación dentro de las llamadas de retorno pronto comenzarán a verse así:

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

El infierno Callback

El escenario en el que las llamadas de retorno están anidadas en varios niveles en otras llamadas de retorno, lo que puede dificultar la comprensión y el mantenimiento del código.

 

Promises (promesas) en acción

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);
});

PromiseFunction devuelve una Promise que representa el proceso de esta función. La función de resolución señala la instancia de promesa cumplida.

Después, podemos llamar a .then() y .catch() en esa función promise:
then — Ejecuta una llamada de retorno que usted le pasa cuando la promesa ha terminado.
catch — Ejecuta una devolución de llamada que le pasas cuando algo sale mal.

 

Funciones Async (asincronas)

La función Async nos proporciona una sintaxis limpia y concisa que nos permite escribir menos código para conseguir los mismos resultados que prometemos.

Las funciones de asincronía se crean preparando la palabra async antes de la declaración de función de este modo:

const asyncFunction = async () => {
  // Code
}

Las funciones asíncronas se pueden pausar con la espera, la palabra clave que sólo se puede utilizar en una función de sincronización. Await devuelve lo que sea que devuelva la función de asíncrono cuando esté hecho. Esta es la verdadera diferencia entre promises y async/await:

// Async/Await
const asyncGreeting = async () => 'Greetings';
// Promises
const promiseGreeting = () => new Promise(((resolve) => {
  resolve('Greetings');
}));
asyncGreeting().then(result => console.log(result));
promiseGreeting().then(result => console.log(result));

Async/Await se parece al código síncrono, y el código síncrono es mucho más fácil de entender.

Vamos a seguir con un ejemplo, como mencionamos antes, vamos a construir un Convertidor de Moneda

Conversor de divisas

Aclaración y puesta en marcha del proyecto

El programa incluirá el código de la moneda de la que queremos convertir y el código de la moneda a la que queremos convertir, así como la cantidad de dinero. El programa genera entonces el tipo de cambio correcto basado en los datos de la API.

En esta aplicación vamos a recibir datos de dos fuentes asíncronas:

  1. Currency Layer — Necesitarás registrarte gratuitamente para poder usar la función API Access Key.
  2. Rest Countries — Esta API nos dará información sobre dónde podemos usar la moneda a la que acabamos de convertir nuestro dinero.

Vamos a crear un nuevo directorio y ejecutar npm init, saltar a través de todos los pasos, e instalar axios escribiendo npm i --save axios. Cree un nuevo archivo llamado currency-converter.js.

En primer lugar, requiere axios al escribir: const axios = require(‘axios’);

Nuestro objetivo es tener tres funciones para este programa. Así que, tres funciones asíncronas. La primera función es recopilar datos fetch/datos monetarios. La segunda función es obtener datos sobre los países. Y la tercera función recogerá esta información en un solo lugar y la entregará al usuario.

Primera función - Recepción asincrónica de datos de moneda

Vamos a crear una función asíncrona que va a tomar dos argumentos, desdeCurrency y toCurrency.

const getExchangeRate = async (fromCurrency, toCurrency) => {}

Ahora tenemos que recuperar los datos. Con async/await, podemos asignar datos directamente a una variable; (importante: no olvide introducir la clave de acceso.)

const getExchangeRate = async (fromCurrency, toCurrency) => {
  const response = await axios.get('http://data.fixer.io/api/latest?    access_key=[yourAccessKey]&format=1');
}

Debido a que todo se convierte a partir del euro, vamos a crear una variable llamada euro que es igual a 1/moneda de la que queremos convertir:

const euro = 1 / rate[fromCurrency];

Por último, podemos multiplicar los euros por la moneda a la que queremos convertir:

const exchangeRate = euro * rate[toCurrency];

Nuestra función debería ser así:

const getExchangeRate = async (fromCurrency, toCurrency) => {
  const response = await axios.get('http://data.fixer.io/api/latest?    access_key=[yourAccessKey]&format=1');
  const rate= response.data.rates;
  const euro = 1 / rate[fromCurrency];
  const exchangeRate = euro * rate[toCurrency];
  
  return getExchangeRate;

}

Segunda función - Recepción asincrónica de datos de país

Vamos a crear una función asíncrona que va a tomar currencyCode como argumento:

const getCountries = async (currencyCode) => {}

Como mencionamos antes, vamos a obtener datos y asignarlos a una variable:

const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);

A continuación, haremos un mapa de los datos y devolveremos el nombre del país para cada uno:

return response.data.map(country => country.name);

Aquí está nuestro último código:

const getCountries = async (currencyCode) => {
  const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
  return response.data.map(country => country.name);
};

Tercera y última función - Fusión de todos los elementos

El siguiente paso consiste en crear una función asíncrona que va a tomar fromCurrency, toCurrency y amount como argumentos:

const convert = async (fromCurrency, toCurrency, amount) => {}

Ahora, vamos a obtener los datos de la moneda:

const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);

Segundo paso, obtenemos los datos de los países:

const countries = await getCountries(toCurrency);

Además, guardamos la cantidad convertida en una variable:

const convertedAmount = (amount * exchangeRate).toFixed(2);

Finalmente, le mostraremos al usuario todo:

return `${amount} ${fromCurrency} is worth ${convertedAmount} 
${toCurrency}. You can spend these in the following countries
: ${countries}`;

Nuestro código completo:

const convert = async (fromCurrency, toCurrency, amount) => {
 const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);
  const countries = await getCountries(toCurrency);
  const convertedAmount = (amount * exchangeRate).toFixed(2);
  return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. 
  You can spend these in the following countries: ${countries}`;
};

Añadir try/catch para tratar los casos de error

Debemos usar toda nuestra lógica en el try, y atrapar (catch) el error si lo hay:

const getExchangeRate = async (fromCurrency, toCurrency) => {
  try {
    const response = await       axios.get('http://data.fixer.io/api/latest?access_key=f68b13604ac8e570a00f7d8fe7f25e1b&format=1');
    const rate = response.data.rates;
    const euro = 1 / rate[fromCurrency];
    const exchangeRate = euro * rate[toCurrency];
    return exchangeRate;
  } catch (error) {
    throw new Error(`Unable to get currency ${fromCurrency} and  ${toCurrency}`);
  }
};

Hagamos lo mismo para la segunda función:

const getCountries = async (currencyCode) => {
  try {
    const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);
return response.data.map(country => country.name);
  } catch (error) {
    throw new Error(`Unable to get countries that use ${currencyCode}`);
  }
};

Y como la tercera función sólo funciona con lo que proporcionaban la primera y la segunda, no es necesario verificar los errores. Finalmente, se puede llamar la función y recibir los datos:

convertCurrency('USD', 'HRK', 20)
  .then((message) => {
    console.log(message);
  }).catch((error) => {
    console.log(error.message);
  });

Aquí está nuestro resultado:

20 USD vale 129,90 HRK. Puede gastarlo en los siguientes países: Croacia

¡Hemos terminado!

 

 
by admin Date: 22-02-2019 async await promises callbacks javascript tutorial visitas : 753  
 
 
 
 

Artículos relacionados



Utilizamos cookies propias y de terceros para mejorar nuestros servicios, mostrarle publicidad relacionada con sus preferencias, realizar análisis estadísticos sobre los hábitos de navegación de nuestros usuarios y facilitar la interacción con redes sociales. Si continúa navegando, consideraremos que acepta su uso. Puede cambiar la configuración u obtener más información aquí Política de cookies.