Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Node.js

Node.js async await vs promise vs callback

5.00/5 (4 votes)
28 Jun 2018CPOL2 min read 11.1K  
Node.js async await vs promise vs callback

Normally, Node.js invokes functions asynchronously. Node.js async await, promise and callback come into the picture when you want to execute one function after completion of another function execution.

All these features are introduced one by one in Node.js different version release. Before Node version 7.6, the callbacks were the only way provided by Node to run one function after another.

We will see all three concepts taking real case scenario

Three Tomatoes with Shadows --- Image by © Royalty-Free/Corbis

Requirement is if you have sufficient balance, then you can purchase. All examples below written cannot be directly executed, rather used here to show concept difference.

Example:

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = function(
    userName, password, balanceNeeded, callback) {
  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      callback(true);
    } else {
      callback(false);
    }
  } else {
    callback(false);
  }
}

let purchaseItem = function(itemName, itemCost) {
  try {
    checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost,
        function(response) {
          if (response) {
            placeAnOrderAndDeliver('Name', 'Address');
          } else {
            showWarningOrError('402', 'Insufficient balance!')
          }
        })
  } catch (error) {
    showWarningOrError('400', error.message)
  }
}

Problem of the above way is, for multiple callbacks, it gets messy and causes a lot of troubles.

Later, promise and function chaining introduced in Node.js version

So if you will refactor the above functions into promise and function chaining, it will look like this:

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = new Promise((resolve, reject) => {
  let successMsg = {
    status: '200',
    message: 'Successful transaction!'
  };

  let failureMsg = {
    status: '449',
    message: 'Unsuccessful transaction!'
  };

  let failureLoginMsg = {
    status: '401',
    message: 'Invalid credential!'
  };

  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      resolve(successMsg);
    } else {
      reject(failureLoginMsg);
    }
  } else {
    reject(failureMsg);
  }
});

let purchaseItem = function(itemName, itemCost) {
  try {
    checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost).
        then((response) => {
          placeAnOrderAndDeliver('Name', 'Address');
        }).
        catch((reason) => {
          showWarningOrError(reason.status, reason.message);
        });
  }
  catch (error) {
    showWarningOrError('400', error.message);
  }
};

In this way, the code looks more clear and easily understandable. You can chain multiple functions by adding multiple .then.

In Node v8, await gets released to deal with promise and chaining. Here, there is no need to write .then, simply you need to call prefix await before the function name and call next function usually you call the function. Unless await function executes, the next function will not be executed.

Example using async/await

let placeAnOrderAndDeliver = function(name, address) {
  // Send the item to Dear 'name' staying at this 'address'
}

let showWarningOrError = function(statusCode, error) {
  // Show warning message or error message if no sufficient balance
  // Or if any error happened
}

let checkSufficientBalanceInAccount = new Promise((resolve, reject) => {
  let successMsg = {
    status: '200',
    message: 'Successful transaction!'
  };

  let failureMsg = {
    status: '449',
    message: 'Unsuccessful transaction!'
  };

  let failureLoginMsg = {
    status: '401',
    message: 'Invalid credential!'
  };

  if (logInCredentialValidated) {
    if (balanceInMyAccount > balanceNeeded) {
      resolve(successMsg);
    } else {
      reject(failureLoginMsg);
    }
  } else {
    reject(failureMsg);
  }
});

let purchaseItem = async function(itemName, itemCost) {
  try {
    await checkSufficientBalanceInAccount('testUser', 'testPassword', itemCost);
    placeAnOrderAndDeliver('Name', 'Address');
  }
  catch (error) {
    showWarningOrError('400', error.message);
  }
};

If you will compare promise based example and async/await based example, then you will find last function is the main difference where “let purchaseItem = async function” you can see async keyword before function keyword. Because await should be used inside async function.

Another difference is functions are called in an order, where function called after await function will not execute unless await function completes.

That is all about basic usage and main differences. If you want to know more about promise and async/await go through these references links:

Hope you like it!

Thanks for your time to go through this.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)