Coders Read

Understanding Promise – Javascript

Promise in Javascript

A promise is an object that may produce a single value some time in the future. The value can either be a resolved value or a reason that it’s not resolved. Promises might be in one of 3 possible states listed below – 

  • Pending: Initial State, before the Promise succeeds or fails
  • Resolved: Completed Promise
  • Rejected: Failed Promise

Promise users can attach callbacks to handle the fulfilled value or the reason for rejection. 

The syntax for a promise object is:

let promise = new Promise(function(resolve, reject) {
// executor
});

Difference between Callbacks and Promises?

The main difference between Callback Functions and Promises is that we attach a callback to a Promise rather than passing it. So we still use callback functions with Promises, but in a different way (chaining).

/* Callback */
function getReward(reward, callback) {
if (typeof reward !== 'number') {
callback(null, new Error('Reward is not a number'))
} else {
callback(reward)
}
}

const money = getReward(1200);
console.log(reward);
/* Promise */
function getReward(reward) {
return new Promise((resolve, reject) => {
if (typeof reward !== 'number') {
reject(new Error('reward is not a number'))
} else {
resolve(reward)
}
})
}

getReward(1200).then((reward) => {
console.log(reward)
})

What is Chaining?

There may be instance when we need to call multiple asynchronous requests. In such case after the first Promise is resolved (or rejected), a new process will start to which we can attach it directly by a method called chaining.

So we create a promise:

const myPromise = new Promise((resolve, reject) => { 
if(true) {
setTimeout(function(){
resolve("Promise is resolved!");
}, 1000);
} else {
reject('Promise is rejected!');
}
});

Let’s create another promise

const greetPromise = function() {
return new Promise(function(resolve, reject) {
const message = `Hello, Welcome to Javascript!`;
resolve(message)
});
}

We chain this promise to our earlier “myPromise” operation like so:

const runPromise= function() {
myPromise
.then(greetPromise)
.then((responseMsg) => {
console.log("Success:" + responseMsg);
})
.catch((errorMsg) => {
console.log("Error:" + errorMsg);
})
}

runPromise();

This can be considered as promise chain where subsequent .then() will utilize data from the previous one.

This will output below message to our console – 

Hello, Welcome to Javascript!

Promise and async/await.

Async and await make promises easier to write. async makes a function return a Promise while await makes a function wait for a Promise. 

Guess the output for below code.

async function getOutput() {
    return await Promise.resolve(‘Hello world’);
}

const data = getOutput();
console.log(data);

Answer

Since we are using async here, the function will return a promise. But the await still has to wait for the promise to resolve. The pending promise gets returned when we call getOutput() in order to set data equal to it.

If we wanted to get access to the resolved value “Hello world”, we could have used the .then() method on data:

data.then(res => console.log(res))

This will log “Hello world” in the console.

Promise.race() and setTimeout

The Promise.race() static method accepts a list of promises and returns a promise that fulfils or rejects as soon as there is one promise that fulfils or rejects, with the value or reason from that promise.

Guess the output for below code.

const promiseOne = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, ‘one’);
});

const promiseTwo = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, ‘two’);
});

Promise.race([promiseOne, promiseTwo]).then(resolve => console.log(resolve));

Answer

In the above code, Promise.race() resolves/rejects the first promise that resolves/rejects. To the setTimeout method, we pass a timer 1000ms for the first promise (promiseOne) and 500ms for the second promise (promiseTwo). This means that the secondPromise resolves first with the value of ‘two’. 

Hence, resolve now holds the value of ‘two’, which gets logged in the console.

Promise with error handler

Guess the output for below code.

const myPromise = new Promise((resolve, reject) => {
    reject(Error('Throw an error'));
})
.catch(error => console.log(error))
.then(error => console.log(error));

Answer

If you throw an error inside the promise, the catch() method will catch it, not the try/catch. The catch function implicitly returns a promise, which can obviously be chained with a then. 

Now since we are not returning anything from the catch block. Thus when error is logged in, the catch block will display the error message where as the then block displays undefined

Sourabh Sinha

Add comment

Follow us

Feel free to get in touch. I love meeting interesting people and making new friends.

Any suggestions will be appreciated.