Promises help us to manage the flow of code execution when working with tasks that might take some time to complete or not completed yet but will be completed in future either with success or failure such as making network requests, reading files. Promises provide a way to handle asynchronous operations and their end result.
Promises have three States
- Pending
- Fulfilled
- Rejected
Let’s understand promises with example of withdrawing money from ATM
Suppose you're going to withdraw money from an ATM Machine 🏧. You insert essential details for withdrawal like amount pin etc. This process sends a request to the bank's server to check your account balance and this process will take some time. If a sufficient amount is available for withdrawal then it will resolve your request and deduct the amount from your account and dispense cash. If amount is not sufficient then it will reject your request and sends error message “Insufficient Amount”
function withdrawingFromATM(amount) {
const balance = 1000;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (amount <= balance) {
const withdrawalAmount = balance - amount;
resolve(`withdraw amount ${withdrawalAmount}`);
} else {
reject(`Insufficient funds!!!`);
}
}, 2000);
});
}
withdrawingFromATM(5000)
.then((message) => {
console.log(message);
})
.catch((error) => {
console.error(error);
});
Promise Methods
Promise.all
Promise.all() is a function that takes an array of promises as input and returns a single promise.This promise is resolved If all the promises given to it are resolved, if any one of them is rejected then promise.all will be rejected.
Promise.all() is a function that takes an array of promises as input and returns a single promise.This promise is resolved If all the promises given to it are resolved, if any one of them is rejected then promise.all will be rejected.
Promise.any
Promise.any() is a method that takes an array of promises as input and returns a single promise. This single promise will fulfil if any of the input promise is fulfilled or it rejects if all the input promise is failed.
Promise.any() is a method that takes an array of promises as input and returns a single promise. This single promise will fulfil if any of the input promise is fulfilled or it rejects if all the input promise is failed.
Promise.allSettled
Promise.allSettled() is a method that takes an array of promises as input and returns a single promise. This single promise will fulfil if all of the input promise is fulfilled with array of objects which defines end result of each promise
Promise.allSettled() is a method that takes an array of promises as input and returns a single promise. This single promise will fulfil if all of the input promise is fulfilled with array of objects which defines end result of each promise
// Let’s Consider a example of withdrawal money from multiple accounts
const promisesArray = [
printAccountStatement(""),
printAccountStatement("account2"),
printAccountStatement("account3")
];
function printAccountStatement(account) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (account && account.length > 0) {
resolve(`${account}'s monthly statement`);
} else {
reject(`Invalid account Number`)
}
}, 500);
});
}
// Promise.any Example
Promise.any(promisesArray).then(results => {
console.log(`\nresult ${results}`)
})
.catch(error => {
console.log(`Error: ${error}`)
});
// Promise.all Example
Promise.all(promisesArray)
.then(results => {
results.forEach(result => {
console.log(`\nresult ${result}`)
})
})
.catch(error => {
console.log(`Error: ${error}`)
});
// Promise.allSettled Example
Promise.allSettled(promisesArray)
.then(results => {
results.forEach(result => {
console.log(`\nresult ${result.status}`)
})
})
.catch(error => {
console.log(`Error: ${error}`)
});
Promise Chain
Promises Chain is used to handle a number of asynchronous operations that are depending on each other. In the promise chain output of the first asynchronous operation is used as the input of the second one.
Let’s understand promise chain with example of ATM Machine
Suppose you are going to withdraw money from money. When you perform a withdrawal money transaction from an ATM, It performs a chain of promises to handle various operations. It will perform a sequence of steps for withdrawal. First, It will check the balance of your account. If sufficient balance is available for withdrawal then another promise that will deduct the amount from your account after deducting the amount of money another promise will print receipt for withdrawal operation.
var balance = 1000;
function checkBalance() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (balance != 0) {
resolve(balance);
} else {
reject("Balance is 0")
}
}, 1000);
});
}
function withdraw(amount) {
return new Promise((resolve, reject) => {
setTimeout(() => {
balance = balance - amount
if (amount <= balance) {
resolve(amount);
} else {
reject("Insufficient balance");
}
}, 500);
});
}
function printReceipt(amount) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Withdrawal Amount: ${amount} and your current balance is ${balance}`);
}, 500);
});
}
checkBalance()
.then(balance => {
console.log(`Your account balance is ${balance}`);
return withdraw(490);
})
.then(withdrawalAmount => {
return printReceipt(withdrawalAmount);
})
.then(receipt => {
console.log(receipt);
})
.catch(error => {
console.error(`Error: ${error}`);
});
Async/Await
Callback hell means a situation in JavaScript where nested callbacks are used to handle asynchronous operations. This makes our code difficult to read, understand, and debug due to complexity. To resolve this async/await is used. async/await, which provide more structured and readable ways to handle asynchronous operations.
An async function is a function that always returns a promise. It allows you to use the await keyword within the function. The await keyword is used to pause the execution of an async function until the promise is resolved or rejected. we can use try/catch blocks to handle errors in async functions. How to use async/await you can refer to the below example.
var balance = 1000;
function checkBalance() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (balance != 0) {
resolve(balance);
} else {
reject("Balance is 0")
}
}, 1000);
});
}
function withdraw(amount) {
return new Promise((resolve, reject) => {
setTimeout(() => {
balance = balance - amount
if (amount <= balance) {
resolve(amount);
} else {
reject("Insufficient balance");
}
}, 500);
});
}
function printReceipt(amount) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Withdrawal Amount: ${amount} and your current balance is ${balance}`);
}, 500);
});
}
async function withdrawMoney() {
try{
console.log("withdrawing process started")
let balance = await checkBalance()
let withdrawalAmount = await withdraw(490)
let receipt = await printReceipt(withdrawalAmount)
console.log("receipt", receipt)
}catch(error) {
console.log(`Error: ${error}`)
}
}
withdrawMoney()