Promises in JavaScript — A quick exploration

Ampaire Phemia
4 min readMay 27, 2020

--

… that whoever is reading this post will understand promises better by the end of this article.

JavaScript promises are quite similar to the promises we make day-to-day. The promises are either fulfilled or broken.

When it comes to JavaScript, a promise that is fulfilled is said to be resolved while that that is broken is said to be rejected. Promises replaced callback functions that were used to handle asynchronous operations.

Asynchronous operations required multiple callbacks and these would make code unmanageable. Luckily, JavaScript introduced promises natively in ES6 saving us the callback hell.

Promises

When I started working on JavaScript, some of the articles suggested that Javascript is an asynchronous language while others stated that it was synchronous. This really frustrated me.

I will just save you this frustration by telling you that “JavaScript is an asynchronous programming language”. And with callback functions, we can make it function like Asynchronous programming language.

A promise: noun: Assurance that one will do something or that a particular thing will happen.

A promise is an object which can be returned synchronously from an asynchronous function. It is returned in one of these possible states:

  • Pending: Not yet fulfilled or rejected
  • Resolved: This will be called when a promise is fulfilled if resolve()
  • Rejected: This will be called when a promise is not fulfilled for example if reject() is called.

Prototypes

As we saw earlier, a promise has three methods. When a promise is created, it is in a Pending state. One or more of the three methods will be run when a promise is settled based on whether a promise is fulfilled or rejected.

Promise.prototype.catch(onRejected)Promise.prototype.then(onFulfilled, onRejected)Promise.prototype.finally(onFinally)

The below image shows the flow for .then and .catch methods. They are chained as shown in the diagram since they return a promise. If (.finally) is declared for a promise, then it will be executed whenever a promise is settled irrespective of whether it is fulfilled or rejected.

Flow for .then and .catch methods

A practical example of how promises work

The ES6 promise constructor takes a function. That function takes two parameters, resolve() and reject(). Let’s look at this scenario to better understand promises.

A daughter asks her mother for money to go to a beach party with her friends. The mother tells her she does not have enough money for the trip but she was expecting Molly (One of her friends)to pay back the money she had lent her. Let’s use JavaScript to see how this promise is executed.

let MumsPromise = new Promise(function(resolve, reject) {
MumsSavings = 600;
TripExpense = 900;
if (MumsSavings > TripExpense) {
resolve({
Day: "Saturday",
Time: "11:00 am- 6:30 pm"
});
} else {
reject("We do not have enough savings");
}
});
MumsPromise.then(function(value) {
console.log("Yay! The party is on, Mum already got me a ticket!", JSON.stringify(value));
});
MumsPromise.catch(function(reason) {
console.log("Mom coudn't buy me the ticket because ", reason);
});
MumsPromise.finally(function() {
console.log("I know Mum cannever fail to buy me a ticket if she has the money");
});

The output of this code will be

case1

Let’s assume Molly had paid the 600 money that she owed to the mother, then her mother’s savings would now be 1200 money.

case2

In case1, the promise is rejected because the mother is 300 cash short while in case2, the promise is resolved and the daughter goes to the beach party.

Promise Chaining

Because .then() always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled. Promises allow you to mimic normal synchronous code’s try/catch behaviour.

Like synchronous code, chaining will result in a sequence that runs in serial. In other words, you can do:

fetch(url)
.then(process)
.then(save)
.catch(handleErrors)
;

Our JavaScript code would them become;

let MumsPromise = new Promise(function(resolve, reject) {
MumsSavings = 600;
TripExpense = 900;
if (MumsSavings > TripExpense) {
resolve({
Day: "Saturday",
Time: "11:00 am- 6:30 pm"
});
} else {
reject("We do not have enough savings");
}
});
MumsPromise.then(
function(value) {
console.log("Hurray I got this phone as a gift ", JSON.stringify(value));
},
function(reason) {
console.log("Mom coudn't buy me the phone because ", reason);
}
);

Important things to note

  • A pending promise may transition into a fulfilled or rejected state.
  • A fulfilled or rejected promise once settled must not transition into any other state.
  • A promise or “thenable” is an object that supplies a standard-compliant .then() method.
  • Once a promise is settled, it must have a value (which can be undefined) and that value must not change.

I hope I kept my promise and you now know what promises are to begin working with them.

Add your comments and let me know where I can make some improvements. Also, clap for me in case you found this article helpful.

Follow me on Twitter, Facebook, LinkedIn

--

--

Ampaire Phemia
Ampaire Phemia

Written by Ampaire Phemia

Remote Full-Stack Developer and Technical Mentor. My preferred stacks are Ruby on Rails, JavaScript, and ReactJs. On rare occasions, I do Python programming.