Javascript Promises – What is it? How to Create? How to Consume? When to use it?

Using Promises:
A Promise in short:
“Imagine you are a kid. Your mom promises you that she’ll get you a new phone next week.”
That is a promise. A promise has 3 states. They are:
1. Promise is pending: You don’t know if you will get that phone until next week.
2. Promise is resolved: Your mom really buy you a brand new phone.
3. Promise is rejected: You don’t get a new phone because your mom is not happy.
Creating a Promise:

Syntax is:

new Promise(resolve, reject)=>{
    //when the result is successful, call 
        resolve(your_success_value);
    //if the result fails, call
    reject(your_fail_value)    
}

Example:

const willIGetNewPhone = new Promise(
    (resolve, reject) => { // fat arrow
        if (isMomHappy) {
            const phone = {
                brand: 'Samsung',
                color: 'black'
            };
            resolve(phone);
        } else {
            const reason = new Error('mom is not happy');
            reject(reason);
        }
 
    }
);
Consuming Promises:
1. We have a function call askMom. In this function, we will consume our above promise willIGetNewPhone.
2. We want to take some action once the promise is resolved or rejected, we use .then and .catch to handle our action.
3. In our example, we have function(fulfilled) { … } in .then. What is the value of fulfilled? The fulfilled value is exactly the value you pass in your promise, it is our phone details in this case.
4. We have function(error){ … } in .catch. What is the value of error? As you can guess, the error value is exactly the value you pass in your promise reject(your_fail_value). Therefore, it will be reason in our case.
// call our promise
 
const askMom = () => {
      willIGetNewPhone
        .then((fulfilled)=>
            // yay, you got a new phone
            console.log(fulfilled);
        )
        .catch((error)=> 
          // oops, mom don't buy it
        console.log(error.message);
        )
};
 
 
askMom();

Chaining Promises:

Let’s say, you, the kid, promise your friend that you will show them the new phone when your mom buy you one.

That is another promise. Let’s write it!

const showOff = (phone) => {
    const message = `Hey friend, I have a new ${phone.color} ${phone.brand} phone`;
    return Promise.resolve(message);
};

Notes:
In this example, you might realize we didn’t call the reject. It’s optional.
We can shorten this sample like using Promise.resolve instead.

Now Let’s chain the promises. You, the kid can only start the showOff promise after the willIGetNewPhone promise.

const askMom = function () {
    willIGetNewPhone
        .then(showOff)
        .then(fulfilled => console.log(fulfilled)) // fat arrow
        .catch(error => console.log(error.message)); // fat arrow
};
 
askMom();

That’s how easy to chain the promise.

Promises are Asynchronous:

example:

const askMom =  () => 
{
    console.log('before asking Mom'); // log before
 
    willIGetNewPhone
        .then(showOff)
        .then((fulfilled) => {
            console.log(fulfilled);
        })
        .catch( (error) => {
            console.log(error.message);
        });
    console.log('after asking mom'); // log after
}

What is the sequence of expected output? Probably you expect:
1. Before asking mom
2. Hey friend, I have a new black Samsung phone.
3. After asking mom

However, the actual output sequence is:

1. Before asking Mom
2. After asking mom
3. Hey friend, I have a new black Samsung phone.

You, the kid, wouldn’t stop playing while waiting for your mom promise (the new phone). Don’t you? That’s something we call asynchronous, the code will run without blocking or waiting for the result. Anything that need to wait for promise to proceed, you put that in .then().

ES7 syntax for Promise

ES7 – Async Await make the syntax look prettier

ES7 introduce async and await syntax. It makes the asynchronous syntax look prettier and easier to understand, without the .then and .catch.
Rewrite our example with ES7 syntax.

* ES7 */
const isMomHappy = true;
 
// Promise
const willIGetNewPhone = new Promise(
    (resolve, reject) => {
        if (isMomHappy) {
            const phone = {
                brand: 'Samsung',
                color: 'black'
            };
            resolve(phone);
        } else {
            const reason = new Error('mom is not happy');
            reject(reason);
        }
 
    }
);

// 2nd promise

async function showOff(phone) {
    return new Promise(
        (resolve, reject) => {
            var message = 'Hey friend, I have a new ' +
                phone.color + ' ' + phone.brand + ' phone';
 
            resolve(message);
        }
    );
};

Calling our promise

// call our promise
async function askMom() {
    try {
        console.log('before asking Mom');
 
        let phone = await willIGetNewPhone;
        let message = await showOff(phone);
 
        console.log(message);
        console.log('after asking mom');
    }
    catch (error) {
        console.log(error.message);
    }
}
 
(async () => {
    await askMom();
})();

Whenever you need to return a promise in a function, you prepend async to that function.
E.g. async function showOff(phone)

Whenever you need to call a promise, you prepend with await.
E.g. let phone = await willIGetNewPhone;
and let message = await showOff(phone);.

Use try { … } catch(error) { … } to catch promise error, the rejected promise.

Why Promises and When to Use Them?

When you are making a remote call to get result, you need to wait, you can’t get the result immediately.
You are not certain that you will get the result because the server might be down,
slow in response, etc. You don’t want your entire process to be blocked while waiting for the result.

Examples are – Calling APIs, downloading files, reading files are among some of the usual async operations that you’ll perform.

Leave a Comment