Basics about Promise-JavaScript.

Veronika Dodda
4 min readAug 17, 2020

JavaScript is single-threaded language, meaning that two bits of a script cannot run at the same time; they have to run one after another, it’s synchronous. As human beings, we’re multithreaded. We can type with multiple fingers, we can drive and hold a conversation at the same time.

Promise helps to run the fetch()function that retrieves data asynchronously. It means we don’t need to wait for one function to finish executing before another one started to run. It's a global method on the window object.

fetch("string representing a URL to a data source")
.then(function(response) {return response.json();
})
.then(function(json){ // data of `json` to be able to manipulate DOM
})

The function above returns an object that represents what the data source sent back. It doesn’t return the actual content. It’s important to call then() method right after. It takes as its argument a function that receives the response. In the end, it will return the content that has gotten out of the response and it comes in json (a collection of JSON return — language-agnostic way of formatting data) or text.

For example, if we fetch()the pokemon API (application programming interface), we can see that the return is Promise(pending).

If we take a look at the details, the Promise status is ‘fulfilled”. It means it was successfully resolved.

A Promise has four states: fulfilled( promise succeeded), rejected( promise failed), pending( promise is still pending), settled (promise has fulfilled or rejected).

A Promise can be created using Promise constructor.

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

Promise constructor takes only one argument, a callback function. Callback function takes two arguments, resolve and reject. Upon performing operations inside the callback function if everything went well then call resolve, otherwise the call reject.

let promise = new Promise(function(resolve, reject) {
const x = "Hello Promise";
const y = "Hello Mr. Promise"
if(x === y) {
resolve();
} else {
reject();
}
});

Promises can be consumed by registering functions using .then and .catch methods.

  1. then()
  • .then() is invoked when a Promise is either resolved or rejected.
  • .then() method takes two functions as parameters.

The first function is executed if Promise is resolved and a result is received. The second function is executed if Promise is rejected and an error is received. It is optional and there is a better way to handle error using .catch() method

2. catch()

  • .catch() is invoked when a promise is either rejected or some error has occurred in execution.
  • .catch() method takes one function as a parameter.
  • .catch() is just a shorthand for .then(null, errorHandler) )
promise
.then(function () {
console.log('Success!');
})
.catch(function () {
console.log('Some error has occured');
});

Output:'Some error has occured'

Chaining after the catch. It’s possible to chain after a failure(a catch), which is useful to accomplish new actions even after an action failed in the chain.

promise
.then(function () {
console.log('Success!');
})
.catch(function () {
console.log('Some error has occured');
});
.then(() => {
console.log('Do this, no matter what happened before');
});

There are common mistakes that a user can make while working with Promises:

// Bad example!

doSomething()
.then(function(result) {
doSomethingElse(result) // Forgot to return promise from inner //chain + unnecessary nesting
.then(newResult => doThirdThing(newResult));
})
.then(() => doFourthThing());
// Forgot to terminate chain with a catch!
  1. Not properly chain things together. This happens when we create a new promise but forget to return it. As a consequence, the chain is broken, or we have two independent chains racing. This means doFourthThing() won't wait for doSomethingElse() or doThirdThing() to finish, and will run in parallel with them, likely unintended. Separate chains also have separate error handling, leading to uncaught errors.
  2. Unnecessarily nests, enabling the first mistake. Nesting also limits the scope of inner error handlers, which — if unintended — can lead to uncaught errors. A variant of this is the promise constructor anti-pattern, which combines nesting with redundant use of the promise constructor to wrap code that already uses promises.
  3. Forgetting to terminate chains with catch. Unterminated promise chains lead to uncaught promise rejections in most browsers.

A good rule-of-thumb is to always either return or terminate promise chains and as soon as you get a new promise, return it immediately, to flatten things:

doSomething()
.then(function(result) {
return doSomethingElse(result);
})
.then(newResult => doThirdThing(newResult))
.then(() => doFourthThing())
.catch(error => console.error(error));

Why choose promises over callback block functions? Here are some advantages:

  • Improves Code Readability
  • Better handling of asynchronous operations
  • Better flow of control definition in asynchronous logic
  • Better Error Handling.

--

--