• Homeright arrow
  • Blogright arrow
  • How to Enhance Your Code with JavaScript Promises
Feature

How to Enhance Your Code with JavaScript Promises

Introduction

JavaScript is a language built to handle asynchronous operations seamlessly, and one of the most powerful tools for managing such operations is the Promise. Introduced in ECMAScript 6 (ES6), Promises provide a more readable and flexible way to deal with asynchronous tasks than traditional callback functions.

What is Promise?

A JavaScript Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Compared to traditional callback functions, promises provide a cleaner, more flexible way to handle asynchronous tasks. Besides, in the Fetch API it is very necessary to understand the behaviour of Promise.
A Promise can be in one of three states:

  1. Pending: The initial state is neither fulfilled nor rejected.
  2. Fulfilled: The operation was completed successfully.
  3. Rejected: The operation failed.

Once a promise is either fulfilled or rejected, its state becomes immutable.

Creating a Promise

  • A Promise is created using the Promise constructor, which takes a function (called the executor function) as an argument.
  • The executor function has two parameters: resolve and reject, which are callbacks used to control the state of the Promise.

Example of Promise Creation:

const promise = new Promise((resolve, reject) => {
// Perform asynchronous operation
let success = true; // Example condition


if (success) {
resolve("Operation successful!");
} else {
reject("Operation failed.");
}
});

Handling a Promise

  • After creating a Promise, its result can be handled using the .then() method for resolved cases, and .catch() for rejected cases.
  • The .finally() method can be used for actions that should be executed regardless of the Promise's outcome.

Example of Promise Creation:


promise
.then((result) => {
console.log(result); // Handles the resolved value
})
.catch((error) => {
console.error(error); // Handles the rejected value
})
.finally(() => {
console.log("Promise completed.");
});

Chaining Promises

One of the most powerful features of Promises is their ability to chain. Each .then() returns a new Promise, allowing you to chain multiple asynchronous operations:

Example of Promise Creation:

fetchData()
.then(response => processResponse(response))
.then(processedData => saveData(processedData))
.then(() => {
console.log("All operations completed successfully.");
})
.catch(error => {
console.error("An error occurred:", error);
});

Promise Methods

1. Promise.all(iterable)

  • Waits for all promises in the iterable to resolve or reject.
  • Returns a single promise that resolves to an array of resolved values.
  • If any promise is rejected, the returned promise is rejected immediately with the reason.

Example of Promise Creation:

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});


Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// Expected output: Array [3, 42, "foo"]

2. Promise.allSettled(iterable)

  • Waits for all promises in the iterable to either resolve or reject.
  • Returns a single promise that resolves to an array of objects describing the outcome of each promise ({status, value} for resolved and {status, reason} for rejected).
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) =>
setTimeout(reject, 100, 'foo'),
);
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) =>
results.forEach((result) => console.log(result.status)),
);
// Expected output:
// "fulfilled"
// "rejected"

3. Promise.any(iterable)

  • Waits for any promise in the iterable to resolve.
  • Resolves with the first resolved value.
  • Rejects if all promises are rejected.
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// Expected output: "quick"

4. Promise.race(iterable)

  • Waits for the first promise in the iterable to settle (resolve or reject).
  • Resolves or rejects based on the outcome of the first settled promise.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
// Expected output: "two"

5. Promise.resolve(value)

  • Returns a promise that resolves with the given value.
  • If the value is a promise, it is returned as-is.
const promise1 = Promise.resolve(123);
promise1.then((value) => {
console.log(value);
// Expected output: 123
});

6. Promise.reject(reason)

  • Returns a promise that is rejected with the given reason.
function resolved(result) {
console.log('Resolved');
}
function rejected(result) {
console.error(result);
}
Promise.reject(new Error('fail')).then(resolved, rejected);
// Expected output: Error: fail

Conclusion

A key component of contemporary JavaScript development is promises. They simplify and prevent errors in the management of asynchronous programming. They allow programmers to design clear, understandable, and manageable asynchronous logic when combined with async/await. Having a solid understanding of Promises will greatly improve your ability to use JavaScript.

Contact staticmania.com for more:

• Web Development Guides

• Performance Optimization

• Frontend Solutions

• Backend Solutions

• Next.js Sites

• ReactJS Solutions

• Design System

footer-particlefooter-particlefooter-particlefooter-particlefooter-particle
back-to-top