My Code Docs

My Code Docs

  • Docs
  • Projects
  • Components
  • Help

›Javascript

Javascript

  • Promises and Asnyc/Await
  • Local Storage
  • Firebase
  • JS Language Basics
  • JS Array Functions
  • Keyboard and Mouse Input
  • ES6 Cheatsheet
  • ESLint Setup
  • Data Structures
  • Naming Conventions
  • Javascript Resources
  • Javascript Snippets
  • npm Module Creation

Node

  • Node JS Basics
  • Server Config and SSH

NextJS

  • NextJS Basics

JS/React Libs

  • Lodash Library
  • Axios
  • Ramda
  • Moment JS
  • Overmind
  • Redux Forms npm Module
  • React Beautiful DnD
  • Ant Design
  • Zustand State Managment

React

  • React Basics
  • React Hooks
  • React With Classes
  • Reach Router
  • React Router
  • React Components

Redux

  • Redux in React
  • My Redux Pattern
  • Redux with React (First Doc)
  • Simple Redux Package

ReactNative

  • React Native
  • React Navigation V5
  • React Navigation V4

HTMLCSS

  • HTML and CSS Snippets
  • Tailwind CSS

Electron

  • Electron React Boiler
  • Electron Basics
  • Electron Packaging
  • Electron Tooling

Promises and Async/Await

Promises

Most important thing to understand about promises is how they are processed. Meaning, if you have a function called myPromise that returns a promise:

    function test() {
    console.log("First Line in function");
        myPromise.then((data) => {
            console.log("Resolved Promise");
        });
        console.log("Line 4 in function");
    }
    //**************
    //--Output
    //First Line in function
    //Line 4 in function
    //Resolved Promise

The code will run to completion before the .then on a promise is even checked if it is resolved.

Async/Await feature of ES6

You must understand that the async/await feature is built on top of promises.

To give an example of using async/await, we will first need to have a function that returns a promise to work with:

//Simple function that returns a promise and will resolve with a message in 'amount' of time.
function breathe(amount) {
  return new Promise((resolve, reject) => {
    if (amount < 500) {
      reject('That is too small of a value');
    }
    setTimeout(() => resolve(`Done for ${amount} ms`), amount);
  });
}

Next, we need to create an async function to work with the promise:

//an async function must begin with keyword 'async'
async function go() {
  console.log(`Starting to breathe`);
  const res = await breathe(1000);
  console.log(res);
  const res2 = await breathe(500);
  console.log(res2);
  const res3 = await breathe(750);
  console.log(res3);
  const res4 = await breathe(900);
  console.log(res4);
  console.log('end');
}

You must begin a function that is going to use await with the keyword async.

Keep in mind that this is essentially creating a function that will be synchronous, but only when the code is running inside of it.

//Using the breathe function and the async function go
console.log('start');
go();
console.log('end');
//result 
//start
//end
//Starting to breathe
//1000
//500
//750
//900

A few key thing to note:

  1. Every async function will return a promise
  2. Most things you await will be a promise
  3. await can only be used inside an async function
  4. async makes that function, in essence, synchronous

Error Handling

There are a couple of ways to handle errors, but on the surface, the async/await is creating synchronous code, so we can just use a try/catch block.

async function go() {
  try {
    const res = await breathe(1000);
    console.log(res);
    const res2 = await breathe(500);
    console.log(res2);
    const res3 = await breathe(750);
    console.log(res3);
  } catch(err) {
    console.err(err);
  }  
  

OR if you don't use a try/catch in your async function, you could put a catch on the calling function:

async function go() {
  const res = await breathe(1000);
  console.log(res);
  const res2 = await breathe(500);
  console.log(res2);
  const res3 = await breathe(750);
  console.log(res3);
}

go().catch((err) => console.log(err));

However, in my testing I have found that if you have a try/catch in the async function and a .catch calling function and there is an error, the try/catch is the one that will be used.

.then() on the async function call

You can use a .then() on the call to the async function. The .then will be run after the function completes and will be passed whatever is returned from the function.

async function go() {
  console.log(`Starting to breathe`);
  const res = await breathe(1000);
  console.log(res);
  const res2 = await breathe(500);
  console.log(res2);
  const res3 = await breathe(750);
  console.log(res3);
  const res4 = await breathe(900);
  console.log(res4);
  console.log('end');
  return ('End of Async GO');
}

//async go will complete and when complete the .then() will run
go().then(val => console.log(`outside then called with - ${val}`));

Higher Order Function to Catch Repetitive Errors

Many times you will want specific error handling for your async functions, however, there will be times when the same errors will need to be handled in multiple async functions.

Instead of duplicating this error handing code over and over again, it is best to use a higher order function to capture and deal with the errors.

Wes Box example in his ES6 Course

The below example also adds parameters that are passed to the go function. This is just to show how these would be handled in the higher order function.

function breathe(amount) {
  return new Promise((resolve, reject) => {
    if (amount < 500) {
      reject('That is too small of a value');
    }
    setTimeout(() => resolve(`Done for ${amount} ms`), amount);
  });
}
//Our Higher Order function
function catchErrors(fn) {
  return function (...args) {
    return fn(...args).catch((err) => {
      console.error('Ohhhh nooo!!!!!');
      console.error(err);
    });
  }
}
async function go(name, last) {
  console.log(`Starting for ${name} ${last}!`);
  const res = await breathe(1000);
  console.log(res);
  const res2 = await breathe(500);
  console.log(res2);
  const res3 = await breathe(750);
  console.log(res3);
  const res4 = await breathe(900);
  console.log(res4);
  console.log('end');
}

const wrappedFunction = catchErrors(go);
wrappedFunction('Wes', 'Bos');

Note that the catchErrors function accepts the function (fn) and then returns a function. The function it returns uses the ...args (spread operator on the args) to accept any number of arguments that may be passed into the async function.

When this higher order function (which has wrapped our async function) finally gets called, we pass the arguments to our async function fn(...args) and tack on a .catch() to handle any errors.

We do return the fn() call, which return a promise that may and may not be used.

Local Storage →
  • Promises
  • Async/Await feature of ES6
    • Error Handling
    • .then() on the async function call
    • Higher Order Function to Catch Repetitive Errors
My Code Docs
Docs
Getting Started (or other categories)Guides (or other categories)API Reference (or other categories)
Community
User ShowcaseStack OverflowProject ChatTwitter
More
BlogGitHubStar
Facebook Open Source
Copyright © 2020 McCoidCo