NodeJs (Javascript) important concepts Series: Promises
What are Promises?
- A promise can be understood as an “Object” -> that returns the value of an asynchronous operation. If this operation was successfully completed, it will return its value, or else it will return an error.
Promise object takes two arguments : resolve and reject.
- We “resolve a value” when we feel our work is done. Resolving a value can be understood as returning some value. How to then use/handle this value?? ….let’s see that later.
Similarily, let’s say we want to throw an error in between our operation, we can do that using “reject” method. Whenever “reject” method is invoked, it becomes an error and how to handle that error …. let’s see that later as well. - Example to see how promises are implemented in code:
let promiseObject = new Promise((resolve, reject) => {
if(5>6)
reject(Error('promise throws error!!'));
else
resolve('promise works!!')
});
console.log(promiseObject)If you execute above code, you will see output: Promise { ‘promise works!!’ } So our Object sends a message(or we call it as sends a promise) and that can be seen in output. In this case, promise can be said to be fulfilled.
- Now, Let’s see another example. In this we have setTimeout function, which pauses the callback function provided for a given time. So in this case, our code will be executed after 1 second.
let promiseObject = new Promise((resolve, reject) => {
setTimeout(() => {
if(5<6)
reject(Error('promise throws error!!'));
else
resolve('promise works!!')
}, 1000)
});
console.log(promiseObject)If you execute above code, you will see output: Promise { <Pending> } Our operation is not yet completed and we are calling promise object before it, hence, promise can be said to be pending.
“You can appreciate the fact that such situations may occur when our asynchronous function is taking some time to execute, but as javascript is synchronous (executes code line by line), it will move forward and not wait for it to complete. For handling those cases we use .then/.catch or async/await. Will talk soon about them”
Note: An important aspect of “asynchronous programming is Promises”. It lets you work on other things, while resolving the promise in coming future. “Promises make Javascript Asynchronous”.
- Let’s see what happens if reject statement is invoked. For that see below code Snippet:
let promiseObject = new Promise((resolve, reject) => {
if(5<6)
reject(Error('promise throws error!!'));
else
resolve('promise works!!')
});
console.log(promiseObject);If you execute above code, you will see output:
(node:6572) UnhandledPromiseRejectionWarning: Error: promise throws error!!
at /tmp/ZcqZ0mbLha.js:4:12
at new Promise (<anonymous>)
at Object.<anonymous> (/tmp/ZcqZ0mbLha.js:2:21)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47Now, from above output, it is clear that reject method throws our error message, but somehow we have to learn how to handle that( ‘unHandledPromiseRejectionWarning’ can be seen in message). We will learn that in next section :)
Promise can be in three states :
- pending if the asynchronous operation is not completed yet,
- fulfilled if the operation is completed (as in above case), and
- rejected the asynchronous function has failed.
Now, when promise is “fulfilled” -> .then() handler is called & when promise is “rejected” -> .catch() handler is called. Let’s see how both cases are handled.
.then() / .catch( )
.then()
So we understood that promises are an object which returns a value. When this is done, we should handle as to what has to be done with that output value. For example, In above cases, we were returning a message “promise works!!” So we can handle them such as:
promiseObject
.then((message) => console.log(message));Output of above message would be promise works!!
Get Rajat Bhardwaj’s stories in your inbox
Join Medium for free to get updates from this writer.
Let’s look at a more generic example:
function add (x, y) {
return new Promise((resolve,reject) => {
var sum = x + y;
if (sum)
resolve(sum);
else
reject(Error("Could not add the two values!"));
});
}
add(4,5) // output of this would be " Promise { 9 } "
.then((sum) => {// value of sum will be 9
console.log('The addition of numbers is: ' sum);
})The output would be : The addition of numbers is: 9
Now as I mentioned above that Javascript is a synchronous language, and it will move ahead whether our task is completed or not.. But what if I want to make it wait till my operation is done? Same thing is achieved by using .then()..This let’s javascript wait till the function completes it’s operation and then executes, whatever is there in .then() . Hope the use is clear now :)
.catch()
Just like we handle resolved values from promises, we should handle errors as well (reject message). See example:
let promiseObject = new Promise((resolve, reject) => {
if(5<6)
reject(Error('promise throws error!!'));
else
resolve('promise works!!')
});
promiseObject
.then((message) => console.log(message))
.catch((err) => console.log('error : ' , err.message))The flow would take us to catch block and output would be error : promise throws error!!
Async/Await:
When I was telling you about ‘resolve’, I told you that it’s very similar to ‘return’ statement. But what if we could directly use return and had a way to mark that it is a promise? We can do that using async keyword.
“async keyword is applied before a function. When this is done, it is assured that the function returns a Promise”
Example:
async function sayHi() {
return "hi Stranger!"
}
console.log(sayHi()); // outputs => Promise { 'hi Stranger!' }
// or now that you have learnt handling promises
sayHi()
.then((message) => console.log(message)); // outputs => hi Stranger!So Now we understood how can we make a function return a promise without making an object and so on….
Remember earlier I mentioned that (while discussing .then() ), Javascript is a synchronous language(means it runs code line by line and waits for none). What if I want it to wait till my operation is done? just like we did using .then() remember? For this we use “await” keyword.
“await keyword makes javascript waits until promise resolves or rejects. await only works inside async functions”
Let’s modify our earlier example:
async function promiseFunction (x, y) {
let promiseObject = new Promise((resolve, reject) => {
setTimeout(() => {
if(5>6)
reject(Error('promise throws error!!'));
else
resolve('promise works!!')
}, 3000)
});
let response = await promiseObject;
// program waits 3 seconds for promise to return response
console.log(response); // outputs => promise works!!
}
promiseFunction();try/Catch Block
While working with async/await, we use try/catch blocks for error handling. We put our logic and code in a try block, and throw error, which is further handled in catch block.
Example:
async function promiseFunction() {
try{
throw new Error("promise throws error!!"); // works same as reject
}
catch(err) {
console.log('error: ', err.message); // outputs => promise throws error!!
}
}
promiseFunction();Promise.all()
It is always a good practice to use promise.all() when dealing with multiple promise instances. It allows you to resolve them concurrently and moves ahead only when “either all of them are resolved” or “throws error when first of them fails”
Example:
async function add (x, y) {
try{
let sum = x + y;
if(sum)
return sum;
else
throw new Error('cannot add two values')
}
catch (err) {
console.log("Error occured: ", err.message)
}
}
let promise1 = add(4,5);
let promise2 = add(5,6);
// Note that await only works inside async function, so we create anonymous function:
(async () => {
let result = await Promise.all([promise1, promise2]);
console.log(result); // outputs => [ 9 , 11 ]
})();That’s all you need to know to get started with Promises. Hope you understood well. Feel free to comment or reach out for any queries : )





