Skip to content

Instantly share code, notes, and snippets.

@DeepNeuralAI
Last active May 30, 2019 02:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeepNeuralAI/fe5e13c113fdbd22721e14c58145a517 to your computer and use it in GitHub Desktop.
Save DeepNeuralAI/fe5e13c113fdbd22721e14c58145a517 to your computer and use it in GitHub Desktop.
Async & Await

Asynchronous Functions

Who can wait quietly while the mud settles?
Who can remain still until the moment of action?

- Laozi, Tao Te Ching

ES 2017 (ES8) introduced a new way of writing asynchronous functions.

Before we understand these Async functions, I want to recap and review the fundamentals.

Recap

We've seen callbacks and promises

Callback Example:

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

It could soon turn out to become Callback Hell:

Note: Callback Hell is a situation where callbacks are nested within other callbacks several levels deep, potentially making it difficult to understand and maintain the code.

What is Asynchronous & Synchronous?

async

Javascript is a single threaded language -- meaning it can only do one thing at a time.

In other words, most of the code we have written till this date is synchronous.


Trains Analogy

I really like this example to explain asynchronous versus synchronous.

How are Asynchronous Calls Used?

trains

You have two trains. 

If we run the trains synchronously, one train can not leave the station until the other one comes back.

If we run the trains asynchronously, both trains can leave whenever they want to, as long as they come back to the station at some point

If trains aren't your thing, I'll give you another short example.

Store Analogy

Synchronous - I'll drop you off at the store and wait till you come back
Asynchronous - I'll drop you off at the store and periodically check if you are done

We use asynchronous calls if the order the tasks are done does not matter.

For example, our phones receive updates asynchronously. It doesn't wait for facebook to update, before updating twitter. Or vice versa.

What are promises?

Example: We have a website that loads real time stock data from an API and then processes and formats the data to display to the user.

If we try to process and format the data before the API has fetched the desired information, we are either going to get an error or an empty blank page.

We use Promises to make sure that the API data is formatted and processed after the API call is finished.

Definition:

A Promise is an object representing the eventual completion or failure of an asynchronous operation.

A promise can have three possible states:

  1. Pending  — Asynchronous operation has not completed yet
  2. Fulfilled  — Operation has completed and the Promise has a value
  3. Rejected  — Operation has completed with an error or failed.

In ES6, we learned that we could use fetch which takes in the path to the resource you want to fetch (usually a URL) — and returns a Promise

Promise Details

A promise is comprised of two parts

  1. the initial code to run (ex: fetch)
  2. The callback code that should be called later when the above code completes (ex: processing data, etc.)
examplePromiseFunction()
  .then((result => {...))
  .catch((error) => {...})

.then is a promise method and contains a code block that is called later after examplePromiseFunction() completes (or fulfilled).

.catch is a promise method that contains a code block that might be called later if examplePromiseFunction() raises an exception or is rejected.

Another Example:

fetch('https://real-time-stock-data.com/json')
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
  console.log(finalResult);
})
.catch(failureCallback);

This could get tedious though. Chaining methods is nice, but it would be nice if we could simplify the API call.

Async/Await

async await

Introduced in ES8, Async/Await is the "syntactic sugar"

It gives us two new keywords to use in our code:

  • Async
  • Await

The async function allows us to write clean and concise syntax that accomplishes the same outcome with less code.

We can create an async function by prepending the word async before the function declaration:

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

To create an async function, all we have to do is add the async keyword before the function declaration, like this:

async function asyncFunc() {
  return "Hey there!";
}

One thing to note about async functions, they always return a promise

Async functions can be paused with await, a keyword that can only be used inside an async function.

Await returns whatever the async function returns when it is done.

When do we use it?

If we need to fetch some data and then use that data within our async function, then we will use await to pause the function execution and resume after the data comes in.

Examples

Conventional way:

async function asyncFunc() {
  let data;
  // fetch data from a url endpoint
  axios.get("/some_url_endpoint")
    .then((result) => {
      data = result
    });
  return data;
}

Elegant Way:

async function asyncFunc() {
  // fetch data from a url endpoint
  const data = await axios.get("/some_url_endpoint");
  return data;
}

If we need to use multiple asynchronous functions within our async function, instead of chaining promises, we can do this instead:

async function asyncFunc() {
  // fetch data from a url endpoint
  const response = await axios.get("/some_url_endpoint");
  const data = await response.json();

  return data;
}

Error Handling

We use try..catch to handle errors.

For example:

async function asyncFunc() {
  try {
    // fetch data from a url endpoint
    const data = await axios.get("/some_url_endpoint");
    return data;
  } 
  catch(error) {
    console.log("error", error);
    // appropriately handle the error
  }
}

Challenge (Optional)

Palindrome Checker

Challenge - Currency Converter

In this tutorial, we will build a simple but educational and useful application that is going to improve your overall knowledge of Async/Await.

The program will take in currency code we want to convert from and currency code we want to convert to, as well as the amount of money.

Afterwards, the program will output the correct exchange rate based on the data from the APIs.

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

Currency Layerhttps://currencylayer.com — You’ll need to sign up for free so you can use the API Access Key. This API will provide us with data needed to calculate exchange rate between currencies.

Rest Countrieshttp://restcountries.eu/ — This API will give us information about where can we use the currency we just converted our money to.

How to start:

  1. Create a new directory and run npm init, skip through all the steps
  2. Install axios by typing npm i --save axios.
  3. Create a new file called currency-converter.js.
  4. Use the starter code below...
const axios = require('axios');

// Use the first API URL inside this function
const getExchangeRate = async (fromCurrency, toCurrency) => {
  const response = await axios.get('http://apilayer.net/api/live
    ? access_key = [Your API KEY Here]
    & currencies = EUR,GBP,CAD,PLN
    & source = USD
    & format = 1');
}


// Use the second API URL inside this function
const getCountries = async (currencyCode) => {
  const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);

}

// Complete the function convert given the following arguments:
// Hint: Use the functions you have completed above!
const convertCurrency = async (fromCurrency, toCurrency, amount) => {


}

If we call convertCurrency('USD', 'HRK', 20) we should get the output:

output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment