In JavaScript, a promise is an object that signifies the eventual success or failure of an asynchronous task.
By utilizing Promises in JavaScript, developers can manage asynchronous tasks in a more organized and comprehensible way when compared to conventional callback functions.
States of Promise
There are three states of Promise in JavaScript:
- Pending: It is the initial phase, which represents that the asynchronous operations are still in progress.
- Fulfilled: It indicates that the asynchronous operation has been completed successfully.
- Rejected: It indicates that the operation has failed.
Syntax
The syntax of JavaScript promises is as follows:
let promise = new Promise(function(resolve, reject){
//code to be executed
});
Parameters
- resolve: This function indicates that the promise has been successfully completed and returns a resulting value.
- reject: This function signifies that the promise has been denied due to an error.
Example
const myPromise = Promise.resolve("Hello, Welcome to our tutorial!");
myPromise.then(message => {
console.log(message);
});
Output:
Hello, Welcome to our tutorial!
Methods of JavaScript Promise
JavaScript offers a variety of techniques for working with promises:
Promise.all Method
The Promise.all function in JavaScript accepts an array of promises and halts execution until all promises have been resolved, subsequently returning a single promise. In the event that any promise is rejected, it will promptly reject the overall promise.
Example
Promise.all([
Promise.resolve("Task 1 completed"),
Promise.reject("Task 2 failed")
])
.then((results) => console.log(results))
.catch((error) => console.error(error));
Output:
Task 2 failed
Promise.allSettled Method
The Promise.allSettled method in JavaScript is designed to wait for all provided promises to either fulfill or reject. Upon completion, it returns an array that contains the results of each promise, indicating whether they were fulfilled or rejected.
Example
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Hello'));
const promises = [promise1, promise2];
Promise.allSettled(promises)
.then((results) => results.forEach((result) => console.log(result)));
Output:
{ status: 'fulfilled', value: 3 }
{ status: 'rejected', reason: 'Hello' }
Promise.race Method
In this approach, a promise is returned that either resolves or rejects as soon as the earliest promise completes its operation.
Example
const promise1 = new Promise((resolve) => {
setTimeout(() => resolve('Promise 1 resolved'), 2000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => resolve('Promise 2 resolved'), 1000);
});
Promise.race([promise1, promise2])
.then((value) => {
console.log(value); // Expected output: "Promise 2 resolved"
})
.catch((error) => {
console.error(error);
});
Output:
Promise 2 resolved
Promise.any Method
In JavaScript, the Promise.any function accepts an iterable collection of promises and produces a single promise that resolves immediately when any one of the provided promises is fulfilled. Conversely, if all the promises are rejected, it will result in an AggregateError.
Example
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"
.catch((error) => console.log(error));
Promise.resolve Method
The Promise.resolve function generates a promise that is fulfilled with the specified value.
Example
const promise1 = Promise.resolve(5);
promise1.then((value) => {
console.log(value); // Expected output: 5
});
const promise2 = Promise.resolve("Hello");
promise2.then((value) => {
console.log(value); // Expected output: Hello
});
Output:
5
Hello
Promise.reject Method
In JavaScript, the Promise.reject function generates a new Promise object that is rejected with a specified reason.
Example
Promise.reject("Something went wrong!")
.catch(error => {
console.log("Error:", error);
});
Output:
Error: Something went wrong!
Promise.finally Method
The Promise.finally method in JavaScript invokes a callback function irrespective of whether the promise is fulfilled or rejected, and it is typically employed for executing clean-up operations.
Example
Promise.resolve("Hello")
.then(result => {
console.log(result);
})
.finally(() => {
console.log("This runs no matter what.");
});
Output:
Hello
This runs no matter what.
Why do we use Promise in JavaScript?
There are several advantages to utilizing Promises in JavaScript. A few of these include:
Avoiding Callback Hell
By utilizing promises in JavaScript, you can eliminate the need for nested callbacks, often referred to as callback hell, which can render code challenging to read and manage. Promises enable you to link .then and .catch methods, leading to a more straightforward and organized flow of code.
Improved Error Handling
JavaScript promises offer a mechanism for managing errors that arise in asynchronous tasks. By utilizing the .catch method, you can address any errors encountered throughout the promise chain, thereby simplifying the process of error management and debugging.
Readability and Maintainability
Promises enhance the readability and maintainability of asynchronous programming by offering a straightforward and uniform approach to manage asynchronous tasks. Utilizing the .then and .catch methods allows us to effectively manage both successful outcomes and errors, resulting in code that is simpler to comprehend.
Composing Asynchronous Operations
In JavaScript, promises can be conveniently compared and merged through functions such as Promise.all, Promise.race, and Promise.any. These methods enable you to manage several asynchronous tasks both concurrently and in sequence.
Simplified Syntax with Async/Await
Promises serve as the core building blocks for the async/await syntax, which offers a more synchronous-style approach to crafting asynchronous code. By utilizing async/await, developers can enhance the readability of asynchronous code and simplify the process of working with it.
Error Handling in Promises
In JavaScript, promises incorporate native error management through the implementation of the .catch method. By appending a .catch call at the conclusion of the promise chain, you can intercept and address any errors that arise from any preceding promises.
In the event that any promise within the chain is rejected, the control flow jumps directly to the closest .catch block. This mechanism enables you to manage the error efficiently.
Using .catch
In JavaScript, the .catch method serves the purpose of managing any errors that arise within the promise chain.
Example
new Promise((resolve, reject) => {
throw new Error('Something went wrong');
})
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error.message); // 'Something went wrong'
});
Output:
Runtime Error:
Something went wrong
Conclusion
To summarize, promises serve as a mechanism for managing asynchronous tasks within JavaScript. Grasping the fundamental concepts of states and methods will enable you to create asynchronous code that is both more efficient and easier to read.