A Promise represents something that is eventually fulfilled. A Promise can either be rejected or resolved based on the operation outcome.
ES6 Promise is the easiest way to work with asynchronous programming in JavaScript. Asynchronous programming includes the running of processes individually from the main thread and notifies the main thread when it gets complete. Prior to the Promises, Callbacks were used to perform asynchronous programming.
A Callback is a way to handle the function execution after the completion of the execution of another function.
A Callback would be helpful in working with events. In Callback, a function can be passed as a parameter to another function.
A Callback is a great way when dealing with basic cases like minimal asynchronous operations. But when you are developing a web application that has a lot of code, then working with Callback will be messy. This excessive Callback nesting is often referred to as Callback hell.
To deal with such cases, we have to use Promises instead of Callbacks.
The Promise represents the completion of an asynchronous operation. It returns a single value based on the operation being rejected or resolved. There are mainly three stages of the Promise, which are shown below:
Pending - It is the initial state of each Promise. It represents that the result has not been computed yet.
Fulfilled - It means that the operation has completed.
Rejected - It represents a failure that occurs during computation.
Once a Promise is fulfilled or rejected, it will be immutable. The Promise() constructor takes two arguments that are rejected function and a resolve function. Based on the asynchronous operation, it returns either the first argument or second argument.
In JavaScript, we can create a Promise by using the Promise() constructor.
const Promise = new Promise((resolve,reject) => {....});
let Promise = new Promise((resolve, reject)=>{ let a = 3; if(a==3){ resolve('Success'); } else{ reject('Failed'); } }) Promise.then((message)=>{ console.log("It is then block. The message is: ?+ message) }).catch((message)=>{ console.log("It is Catch block. The message is: ?+ message) })
The Promise methods are used to handle the rejection or resolution of the Promise object. Let's understand the brief description of Promise methods.
This method invokes when a Promise is either fulfilled or rejected. This method can be chained for handling the rejection or fulfillment of the Promise. It takes two functional arguments for resolved and rejected. The first one gets invoked when the Promise is fulfilled, and the second one (which is optional) gets invoked when the Promise is rejected.
Let's understand with the following example how to handle the Promise rejection and resolution by using .then() method.
let success = (a) => { console.log(a + " it worked!") } let error = (a) => { console.log(a + " it failed!") } const Promise = num => { return new Promise((resolve,reject) => { if((num%2)==0){ resolve("Success!") } reject("Failure!") }) } Promise(100).then(success, error) Promise(21).then(success,error)
It is a great way to handle failures and rejections. It takes only one functional argument for handling the errors.
Let's understand with the following example how to handle the Promise rejection and failure by using .catch() method.
const Promise = num => { return new Promise((resolve,reject) => { if(num > 0){ resolve("Success!") } reject("Failure!") }) } Promise(20).then(res => { throw new Error(); console.log(res + " success!") }).catch(error => { console.log(error + " oh no, it failed!") })
It returns a new Promise object, which is resolved with the given value. If the value has a .then() method, then the returned Promise will follow that .then() method adopts its eventual state; otherwise, the returned Promise will be fulfilled with value.
Promise.resolve('Success').then(function(val) { console.log(val); }, function(val) { });
It returns a rejected Promise object with the given value.
function resolved(result) { console.log('Resolved'); } function rejected(result) { console.error(result); } Promise.reject(new Error('fail')).then(resolved, rejected);
It takes an array of Promises as an argument. This method returns a resolved Promise that fulfills when all of the Promises which are passed as an iterable have been fulfilled.
const PromiseA = Promise.resolve('Hello'); const PromiseB = 'World'; const PromiseC = new Promise(function(resolve, reject) { setTimeout(resolve, 100, 1000); }); Promise.all([PromiseA, PromiseB, PromiseC]).then(function(values) { console.log(values); });
This method is used to return a resolved Promise based on the first referenced Promise that resolves.
const Promise1 = new Promise((resolve,reject) => { setTimeout(resolve("Promise 1 is first"),1000) }) const Promise2= new Promise((resolve,reject) =>{ setTimeout(resolve("Promise 2 is first"),2000) }) Promise.race([Promise1,Promise2]).then(result => { console.log(result); })
Promise chaining allows us to control the flow of JavaScript asynchronous operations. By using Promise chaining, we can use the returned value of a Promise as the input to another asynchronous operation.
Sometimes, it is desirable to chain Promises together. For example, suppose we have several asynchronous operations to be performed. When one operation gives us data, we will start doing another operation on that piece of data and so on.
Promise chaining is helpful when we have multiple interdependent asynchronous functions, and each of these functions should run one after another.
Let us try to understand the concept of Promise chaining by using the following example:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> const PromiseA = () =>{ return new Promise((resolve,reject)=>{ resolve("Hello Promoise A"); }); } const PromiseB = () =>{ return new Promise((resolve,reject)=>{ resolve("Hello Promise B"); }); } const PromiseC = () =>{ return new Promise((resolve,reject)=>{ resolve("Hello Promise C"); }); } PromiseA().then((A)=>{ console.log(A); return PromiseB(); }).then((B)=>{ console.log(B); return PromiseC(); }).then((C)=>{ console.log(C); }); </script> </body> </html>
Execute the above code in the browser and open the terminal by using ctrl+shift+I. After the successful execution of the above code, we will get the following output.