Async/await How They Really Work: An Example

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


Promises give us an easier way to deal sequentially with asynchrony in our code. This is a welcome addition, given that our brains are not designed to deal efficiently with asynchronicity. Async / await functions, help us to write completely synchronous code while performing asynchronous tasks in the background.

The functionality achieved using async functions can be recreated by combining promises with generators, but async functions give us what we need without any extra boilerplate code.

What we will see in this post

  1. Introduction (callbacks, promises, async/await)
  2. Example: Currency Converter that is receiving asynchronous data from two API’s. In this tutorial, we will build a simple and useful application that is going to improve your overall knowledge of Async/Await.

Let's start

A new way to write asynchronous code is Async / Await it's built on promises, so it's not blocking as well.

The big difference is that asynchronous code looks and behaves a little more like synchronous code. This is where all its power lies.

Previous options for asynchronous code were callbacks and promises.

Callbacks in action

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

Problem with callbacks The infamous Callback Hell

Nesting callbacks within callbacks will soon start to look like this:

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

Callback Hell

The scenario in which callbacks are nestled at several levels in other callbacks, which can make it difficult to understand and maintain the code.

 

Promises in action

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 returns a Promise that represents this function's process. The resolution function signals the completed promise instance.

Afterwards, we can call .then() and .catch() on that promise function:
then — Runs a callback you pass to it when the promise has finished.
catch — Runs a callback you pass to it when something went wrong.

 

Async Functions

The Async function provides us with a clean and concise syntax that allows us to write less code to achieve the same results that we promise.

Async functions are created by prepending the word async before the function declaration like this:

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

Asynchronous functions can be paused with waiting, the keyword that can only be used in an async function. Await returns whatever the async function returns when it's done. This is the real difference between promises and async / wait:

// 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 looks similar to synchronous code, and synchronous code is much easier to understand.

Let's proceed with an example, as we mentioned before, we are going yo built a Currency Converter

Currency Converter

Project clarification and setup

The program will include the currency code we want to convert from and the currency code we want to convert to, as well as the amount of money. The program then generates the correct exchange rate based on the API data.

In this application we’re going receive data from two asynchronous sources:

  1. Currency Layer — You’ll need to sign up for free so you can use the API Access Key.
  2. Rest Countries — This API will give us information about where can we use the currency we just converted our money to.

Let's create a new directory and run npm init, skip through all the steps, and install axios by typing npm i --save axios. Create a new file called currency-converter.js.

Firstly, require axios by typing: const axios = require(‘axios’);

Our aim is to have three functions for this program. So, three asynchronous functions. The first function is to collec fethc/ currency data. The second function is to fetch data about countries. And the third function will collect this information in one place and deliver it to the user.

First function — Receiving Currency Data Asynchronously

We’ll create an asynchronous function that is going to take in two arguments, fromCurrency and toCurrency.

 

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

Now we need to fetch the data. With async/await, we can assign data directly to a variable; (important:don’t forget to enter the access key.)

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

Because everything is converted from the euro, we will create a variable called the euro that is equal to 1 / currency from which we want to convert:

const euro = 1 / rate[fromCurrency];

Finally, we can multiply euros by the currency to which we want to convert:

const exchangeRate = euro * rate[toCurrency];

Our function should look like this:

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;

}

Second function — Receiving Country Data Asynchronously

Let's create an asynchronous function that is going to take currencyCode as an argument:

const getCountries = async (currencyCode) => {}

As we mentioned before, we are going to fetch data and assign it to a variable:

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

We’ll then map over the data and return country.name for each:

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

Here's our finally code:

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

Third and final function - Merging it all together

The next step consist in create an asynchronous function that is going to take fromCurrency, toCurrency, and amount as arguments:

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

Now, let's get the currency data:

const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);

Second step, we get the countries data:

const countries = await getCountries(toCurrency);

Furthermore, we save the amount converted to a variable:

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

Finally, we'll show the user everything:

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

s

Our complete code:

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

Adding try/catch to deal with error cases

We must to use all our logic in try, and catch the error if there is one:

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

Do the same for the second function:

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

And since the third function only works with what was provided by the first and second functions, error checks are not necessary. Finally, the function can be called and the data received:

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

Here's our output:

20 USD is worth 129.90 HRK. You can spend this on the following countries: Croatia

We're done!

 

 

 

 

Original source : Adrian Hajdin

 
by admin Date: 22-02-2019 async await javascript tutorial hits : 2889  
 
 
 
 

Related Posts



We use our own cookies and third-party cookies to improve our services, show products based on your preferences, analyse the browsing habits of our users, and enable interaction with social networks. Continuing to browse our sites implies full acceptance of their use. You can change your cookie setting or get more information here: Cookies policy .