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
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.
CodeProject