DEV Community

Cover image for All about Promises in JavaScript
Code of Relevancy
Code of Relevancy

Posted on • Edited on • Originally published at paradiseofcreativity.com

All about Promises in JavaScript

In JavaScript, a Promise is an object that represents a value that may not be available yet, but will be resolved in the future. Promises are used to handle asynchronous operations, such as making network requests or accessing databases, where the result is not immediately available.

I'd like to kick off our adventure, if you're ready..


How Promises Work?

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

How Promises Work


A Promise has three possible states:

A Promise has three possible states

  1. Pending: The initial state of a Promise. The Promise is neither fulfilled nor rejected.
  2. Fulfilled: The Promise has been resolved and the resulting value is available.
  3. Rejected: The Promise has been rejected and an error occurred.

Once a Promise is settled, it cannot be resettled. The resolve() or reject() function can only be called once, and any subsequent calls to these functions will have no effect. The immutability of a settled Promise is an important feature because it ensures that the Promise's value remains consistent and predictable. Once a Promise is settled, its value cannot be changed, which helps prevent unexpected behavior and makes it easier to reason about the code.


How to Create Promises?

A Promise is created using the Promise constructor, which takes a single argument, a function called the executor. The executor function takes two arguments: resolve and reject. These are functions that are called when the Promise is either fulfilled or rejected.

To show you what I mean..

Example of creating a Promise that resolves after a delay

The Promise in above example will resolve after one second, and the value of the resolved Promise will be the array of users.

Once a Promise is created, you can use the then method to attach a callback function that will be called when the Promise is fulfilled. The then method takes two arguments: a callback function for the resolved value and a callback function for the rejected value.

To show you what I mean..

Promise example

Output of promise example


Moving forward on our adventure, let's take a look at an example of a Promise that has been rejected.

To show you what I mean..

Promise that has been rejected

Output of promise that has been rejected


Chained Promises

Below methods are used to associate further action with a promise that becomes settled. As these methods return promises, they can be chained

Promise.prototype.then()
Promise.prototype.catch()
Promise.prototype.finally()
Enter fullscreen mode Exit fullscreen mode

Chaining promises in JavaScript

Chaining promises in JavaScript involves creating a sequence of promises that are executed one after the other. Each promise in the chain depends on the successful completion of the previous promise, so if any promise in the chain fails, the entire chain fails.

Let's see how we can chain promises in JavaScript:

Example of chain promises in JavaScript

Output: Example of chain promises in JavaScript

Here, the fetchData() function is used to fetch data from a remote API and perform some operation on it. The fetchData() function returns a Promise that resolves with the result of the operation.

The Promise chain begins by fetching user data from the API, then using the first user's ID to fetch their posts, and finally using the ID of the first post to fetch the comments for that post. Each then() method in the chain handles the resolved value of the previous Promise and the final catch() method handles any errors that occur during the chain.

We can create many chains with then() method as per the requirements. Like synchronous code, chaining will result in a sequence that runs in serial. Let's see a simple instance..

many chains


Benefits of Promises

Promises provide several benefits over traditional callback based approaches to handling asynchronous operations in JavaScript. Some of the key benefits include:

  1. Better readability: Promises allow you to write code that is more readable and easier to understand than traditional callback-based approaches. With Promises, you can chain together asynchronous operations in a sequence, which makes it clear what order the operations are executed in.

  2. Improved error handling: Promises make it easier to handle errors that occur during asynchronous operations. With Promises, you can use the catch method to handle errors that occur during any step in the chain, rather than having to handle errors separately for each step.

  3. Avoiding callback hell: Promises can help you avoid "callback hell," a situation where you have a chain of nested callbacks that can become difficult to manage and debug. With Promises, you can chain together asynchronous operations without having to nest multiple levels of callbacks.

  4. Ability to return a value: Promises allow you to return a value from an asynchronous operation, which makes it easier to pass the result of one operation to another operation in a sequence. This is particularly useful when you need to perform multiple asynchronous operations in a sequence and need to use the result of each operation in the next operation.

  5. Better compatibility: Promises are a standardized feature in modern JavaScript, and are supported by all modern browsers and Node.js. This means that Promises can be used across different environments without requiring different code for each environment.


How Do I Cancel a Promise?

In modern JavaScript - No, you cannot cancel a Promise once it has been created. It will execute its code and either resolve or reject, and there is no built in way to cancel the operation.

There are some techniques you can use to simulate cancellation:

  1. Timeout: You can use a timeout to reject the Promise if it takes too long to resolve. This technique is useful if you are making a network request and want to limit the amount of time it takes.

  2. Aborting a network request: You can use an abort controller to abort a network request. The Fetch API provides an AbortController API that allows you to cancel a network request before it completes.

  3. Using a flag: You can use a flag in your code to simulate cancellation. You can set the flag to true to indicate that the operation should be canceled, and then check the flag in your Promise code to determine whether to continue or reject the Promise.

It's worth noting that none of these techniques truly cancel a Promise; they simply reject it early. If you need true cancellation, you may need to use a library that provides cancellation support, such as rxjs or bluebird.


Bluebird Promise Cancellation

Bluebird is a popular Promise library for JavaScript that provides advanced features, including Promise cancellation. Promise cancellation is the ability to cancel a Promise, which is useful for canceling ongoing or long running asynchronous operations.

With the help of Bluebird, Promise cancellation is achieved using the Promise.cancel() method. This method is not part of the standard Promise API and is specific to Bluebird.

To use Promise cancellation in Bluebird, you need to create a cancellable Promise using the new Promise() constructor and passing a cancel function as an argument. The cancel function will be called when the Promise is canceled.

Example of Bluebard


Multiple Promises in Parallel

With the help of Promises, it's easier to manage and execute multiple asynchronous operations in parallel and wait for all of them to complete before continuing.

To show you what I mean..

Four promises are created using the new Promise() syntax. Each promise is resolved or rejected after a certain timeout period using setTimeout() method. The error function is defined to log any error to the console.

promises

After creating above promises, now we will see instances of using different Promise methods.

Promise.all() method

Below instance uses Promise.all() method which takes an array of promises and waits for all promises to be fulfilled. Once all the promises are resolved, then() method is executed which returns an array of values in the order they were passed in the promise array. In this case, all three promises are resolved and their values are logged to the console.

This is great way to, e.g. fetch data using two different requests, and then combine them once both requests complete.

Promise.all() method

Promise.any() method

Below instance uses Promise.any() method which takes an array of promises and waits for any one of them to be fulfilled. Once the first promise is resolved, then() method is executed which returns the resolved value of the first promise. In this case, the third promise is resolved before the other two and its value is logged to the console.

Below instance uses

Promise.race() method

Below instance uses Promise.race() method which takes an array of promises and waits for the first promise to be either resolved or rejected. Once the first promise is settled, then() method is executed which returns the resolved or rejected value of the first settled promise. In this case, the third promise is resolved before the other two, so its value is logged to the console.

Promise.race() method

Promise.allSettled() method

Below instance uses Promise.allSettled() method which takes an array of promises and waits for all promises to be settled, i.e., either resolved or rejected. Once all promises are settled, then() method is executed which returns an array of objects, each object containing the status and value or reason of each promise. In this case, all promises are settled, so the status and values or reasons of all promises are logged to the console.

Promise.allSettled() method


Conclusion

The Fetch API is a modern replacement for the older XMLHttpRequest object, and it is based on Promises. When you make a request with the Fetch API, you get back a Promise that resolves to the response object. This allows you to use the then() method to handle the response in a clean and readable way.

Async Functions are a newer addition to JavaScript, and they are built on top of Promises. Async Functions allow you to write asynchronous code that looks like synchronous code, making it easier to read and write. Async Functions use the await keyword to wait for Promises to resolve before continuing, making it possible to write asynchronous code that looks like a sequence of synchronous statements.

In both of these idioms, Promises are used to handle asynchronous operations in a clean and readable way. By using Promises, you can avoid callback hell and write asynchronous code that is easy to reason about..


Motivation

Reminder:
You're awesome no matter what others say and think..

You're awesome no matter what others say and think


πŸ€Support

Please consider following and supporting us by subscribing to our channel. Your support is greatly appreciated and will help us continue creating content for you to enjoy. Thank you in advance for your support!

YouTube
Discord
GitHub


Thank you

Top comments (48)

Collapse
 
ant_f_dev profile image
Anthony Fung

Great article. In addition to this, you can also run multiple promises and only continue once they are all complete using Promise.all. This is great way to, e.g. fetch data using two different requests, and then combine them once both requests complete.

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you for reading my article and your valuable feedback. As per your suggestion, I have updated this article by adding a new section "Multiple Promises in Parallel".

Collapse
 
ant_f_dev profile image
Anthony Fung

A great addition - I've only ever had to use all and occasionally any, so didn't know about race and allSettled until reading it - thanks!

Thread Thread
 
codeofrelevancy profile image
Code of Relevancy

You're welcome..

Collapse
 
mcwolfmm profile image
mcwolfmm

Ok, why are you giving a code with pictures?

Collapse
 
codeofrelevancy profile image
Code of Relevancy

For better representation of my articles. Moving forward, I will add source code as well..
Thank you for valuable feedback. I appreciate it..

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Very excited to announce that we have reached 1K followers in our community. We couldn't have done it without your support and engagement. We want to thank each and every one of you for being a part of our adventure..

We look forward to continuing to grow together & providing even more value to our community.

Happy coding!!!

Collapse
 
cwilby profile image
Cameron Wilby

Excellent post! A lot of this translates into helpful insight when writing async/await functions, which are themselves based on promises!

developer.mozilla.org/en-US/docs/W...

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thanks for reading and feedback..

Collapse
 
dealwith profile image
Gleb Krishin

Thanks for the article! What program are you using for generating such cool code snippets and GIF animations?

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you for your valuable feedback.

I use these tools:
Miro - For diagrams
Canva - For GIF animations
Ray.so Image of code snippets

Collapse
 
dealwith profile image
Gleb Krishin

thanks

Thread Thread
 
codeofrelevancy profile image
Code of Relevancy

You're welcome..

Collapse
 
stakedesigner profile image
StakeDesigner

wow, the great present article

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you..

Collapse
 
adii9 profile image
Aditya Mathur

This is a great blog. I really loved the way promises has been explained with in-depth knowledge. More over the solution of the probelms mentioned made it even better. Keep up the good work.

Collapse
 
codeofrelevancy profile image
Code of Relevancy • Edited

Thank you Aditya for your valuable feedback..

Collapse
 
shallfer7 profile image
Charles Fernandes

Great article, great examples

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you πŸ™ for your valuable feedback..

Collapse
 
amirfcf72 profile image
Amir

Thanks great article

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you Amir, for reading and feedback..

Collapse
 
ypdev19 profile image
Yuli Petrilli

Great article! Saving it to study later because i still struggle when working with promises. Thank u!

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you for your feedback. Glad to hear that you found it useful. Best of luck in your programming journey..