In this blog, I will cover Javascript Promises in Depth. I will discuss all functions related to Promise and Features of Promise.
Javascript Promises in Depth
What is promise?
Promise, in the javascript program, means it promises that I will give you a result after a period of time (usually an asynchronous operation). It is a solution to asynchronous programming. Syntactically speaking, a native Promise is an object, from which asynchronous operation messages can be obtained.
Features of promise
- The state of the object is not affected by the outside world.
A promise has three states pending
(in progress), fulfilled
(successful) and rejected
(failed). Only the result of an asynchronous operation can determine which state it is currently in, and no other operation can change this state.
- Once you change from the waiting state to another state, you can never change the state.
There are only two status changes for promise:pending
(in progress) –> fulfilled
(successful);pending
(in progress) –> rejected
(failed).
When the status change is over, it is called resolve
(fixed). Once the status becomes resolved, it cannot be changed again.
- Once a new Promise is created, it will be executed immediately and cannot be cancelled halfway.
- If the callback function is not set, errors thrown inside the Promise will not be reflected to the outside.
- When it is in the pending state, it is impossible to know which stage it is currently in (just started or is about to be completed).
Promise instance operation

First create a Promise instance
let promise = new Promise ( function ( resolve,reject ){ if ( /*Asynchronous execution succeeded*/ ){ resolve (value); } else { reject (error); } }) promise.then(function (){ //Operation after the callback is successfully executed }, function (){ //The operation after the callback fails, optional });
The Promise constructor accepts a function as a parameter, and the two parameters of the function are resolve and reject. They are two functions, provided by the JavaScript engine. When the asynchronous operation succeeds ( pending--fulfilled
), the resolve(value)
function is called to pass the operation result as a parameter, and when the asynchronous operation fails ( pending--rejected
), the reject(error)
function is called to return the error. After the Promise instance is generated, use then
methods to specify the callback functions for the resolved state and rejected state respectively.
Let’s take a look at the method of constructing function prototype
Promise.prototype.then()
- The function is to add a callback function when the state of the Promise instance changes . Accepts two callback functions as parameters. The first callback function is called when the state of the Promise object becomes resolved, and the second callback function is called when the state of the Promise object becomes rejected. Among them, the second function is optional and does not have to be provided.
- The method returns another Promise object, and then you can call
then
method later.
Promise.prototype.catch()
- It is an alias of
.then(null, rejection)
or.then(undefined, rejection)
, which is used to specify the callback function when an error occurs. The error of the Promise object has a “bubble” nature and will be passed backwards until it is caught. In other words, the error will always be caught by the next catch statement . - The method returns a Promise object, so you can call
then
method later.
The above code can also be understood like this:
getUserDataJSON( '/user.json' ).then(function(user_data) { // ... }).catch ( function ( error ) { // handle errors that occur when getJSON and the previous callback function are running console.log('An error occurred!',error); });
Promise.prototype.finally()
- The method is used to specify the callback function that will be executed regardless of the final state of the Promise object. This method is introduced into the standard by ES2018.
- The method’s callback function does not accept any parameters, which means that there is no way to know whether the previous Promise state is fulfilled or rejected. This shows that
finally
the operation in the method should be independent of the state and not dependent on the execution result of the Promise.
promise.then(()=>{}).catch(()=>{}).finally(()=>{ // operation }); // is equivalent to promise.then(result=>{ // operation return result; }).catch (error=>{ // operation throw error; });
Promise chain call
- If the Promise instance is resolve then it will pass its value to the next success callback so you can chain calls the instance.
- If there is an exception in the then, the next failure callback of the then will be followed, and the catch will catch the exception that was not caught.
Promise.resolve(1).then(res=>{ throw new Error("Error!"); return 2 //Packed into Promise.resolve(2) }).then().then().catch(err=>3).then(res=>console.log(res)) //OUTPUT: Error!
- If return is used in then, then the value of return will be
Promise.resolve()
wrapped, and no parameters can be passed in then. If it is not passed, it will be passed to the next then.
Promise.resolve(1).then(res=>{ console.log(res) //OUTPUT: 1 return 2; //Packed into Promise.resolve(2) }).catch(err=>3).then().then(res=>console.log(res)) //OUTPUT: 3
Promise API
Promise.resolve()
Convert (wrap) existing objects into promise objects. Four parameter types:
- Pass without parameters.It return a new promise object with a state of resolve.
let p = Promise.resolve() // p is promise
- The parameter is a Promise instance. It return the current promise instance
- The parameter of resolve is an object with the then method
let data = { then : function(resolve,reject){ resolve ( 'object with then method' ) } } Promise.resolve(data).then((res)=>console.log(res)) // 'object with then method' is returned
- The parameter is none-empty, none-then method object. It return a new promise object with a resolve state, so the
then
callback function will be executed immediately. The parameters of the method Promise.resolve will be passed to the callback function at the same time.
let p = Promise.resolve('foo') // equivalent to let p = new Promise(resolve=>resolve('foo')) p.then(res=>console.log(res)) //'foo'
Promise.reject()
- When the parameter is a non-then object, the
Promise.reject(reason)
method will also return a new Promise instance whose status isrejected
let p = Promise.reject('error') // equivalent to let p = new Promise ((resolve,reject)=>reject('error')) // callback for handling errors p.then(null,res=>console.log(res)) // 'error'
- The parameter of resolve is the object with the then method.What is returned is not
then
the callback function of the method, but the data object itself
let data = { then : function(resolve,reject){ reject('The object with the then method has an error') } } Promise.resolve(data).then(null,res=>console.log(res)) // data // equivalent Promise.resolve(data).catch(res=>console.log(res)) / /data
Promise.all()
This method wraps multiple promise instances into a new promise instance.
let p = Promise.all([p1,p2,p3])
The parameter does not have to be an array, but it must be an iterable Iterator
, and each returned member (p1, p2, p3) is a Promise instance. If not, the Promise.resolve
() method will be called first to convert the parameter to a Promise instance, and then go further deal with.
var p1 = Promise.all(["InfoHubBlog","Best","Website"]); var p2 = Promise.all(["InfoHubBlog","Best","Website",Promise.resolve(444)]); var p3 = Promise.all(["InfoHubBlog","Best","Website",Promise.reject(555)]); setTimeout(function(){ console.log(p1); // Promise {<state>: "fulfilled", <value>: Array[3]} console.log(p2); // Promise {<state>: "fulfilled", < value>: Array[4]} console.log(p3); // Promise {<state>: "rejected", <reason>: 555} }); p1.then(function(posts) { // ...will call back when there is a return value }). catch ( function ( reason ){ // ... });
- If all Promise are fulfilled then state become fullfilled and the value is passed to
then
callback function. - If any one element in iterator is rejected then the state become rejected and the rejected value is passed to
catch
callback function. - Promise.all() is an asynchronous resolution . Only when the state of all instances has changed
fulfilled
, or one of them has changedrejected
, will the callback functionthen
andcatch
method behind the Promise.all method be called . But if and only if the passed iterable is empty , Promise.all will resolve synchronously
let p1= Promise.all(["Bye"]).then(a=>console.log(a)); let p2= Promise.all([]).then(el=>console.log("Hi")); /* OUTPUT: Hi ["Bye"] */
- Handling errors . Normally, when one of the instances returns
rejected
,Promise.all
thecatch
method will be called and the first error will be returned. But in actual application, we want all instances to return parameters to form an array regardless of success or failure, then we can call the instance’s owncatch
method to avoid this situation.
const p1=new Promise((resolve,reject)=>{ resolve('hello'); //resolved }).then(result=>result).catch(e=>e); const p2=new Promise((resolve,reject)=>{ throw new Error('reported'); //rejected }).then(result=>result).catch(e=>e); Promise.all([p1, p2]) .then(result=>console.log(result)) // ["hello", Error: Error reported] .catch(e=>console.log(e));
P1 will resolved
, p2 will be the first rejected
, but p2 has its own catch method, which returns a new Promise instance, and p2 actually points to this instance. The instance will become resolved after the catch method is executed, causing both instances in the Promise.all() method parameter to be resolved , so the callback function specified by the then method will be called instead of the callback function specified by the catch method.
- The principle of js native implementation of Promise.all
//Add an all method to the Promise class to accept an array of promises passed in Promise.all Promise.all = function(promiseArrs) { return new Promise((resolve,reject) => { //Return a new Promise let arr = []; //Define an empty array to store the result let i = 0 ; function handleData(index,data) { //Data processing function arr[index] = data; i++; if (i === promiseArrs.length) { //When i is equal to the length of the passed array resolve (arr); //Execute resolve and put the result in } } for(let i = 0;i<promiseArrs.length;i++) { //loop through the array promiseArrs[i].then((data)=>{ handleData (i,data); //pass the result and index into handleData function }, reject) } }) }
- If the experience of all is not good, then we can also make some method by ourselves, which means that all failures are considered failures.
Promise.some = function(promiseArrs) { return new Promise((resolve,reject)=>{ let arr = []; //Define an empty array to store the result let i = 0; function handleErr(index,err) { // Error handling function arr[index] = err; i++; if (i === promiseArrs. length ) { //When i is equal to the length of the passed array, reject (err); //Execute reject and put the result in } } for(let i=0;i<promiseArrs.length;i++) { // loop through the array promiseArrs[i].then(resolve,(e)=>handleErr(i, e)) } }) }
Promise.allSettled – Compatibility is not friendly
This method is similar to promise.all, it is to solve the unreasonable appearance of the all method in handling errors. Its parameter accepts an array of Promises and returns a new Promise. The only difference from all is that it will not be short-circuited, which means that when the Promises are all processed, we can get the status of each Promise, regardless of whether the processing was successful.
- Similar to all, when its own instance has a catch callback, the status of each instance becomes
fulfilled
const p3 = new Promise((resolve, reject) => { resolve('hello'); //resolved }).then(result => result).catch(e => e); const p4 = new Promise((resolve, reject) => { throw new Error('Reported an error');//rejected }).then(result => result).catch(e => e); Promise.allSettled([p3, p4]) .then(result => console.log(result)) .catch(e => console.log(e));

- No catch receiving error, return its own status and callback parameters
const p5 = new Promise((resolve, reject) => { resolve('hello'); //resolved }).then(result => result) const p6 = new Promise((resolve, reject) => { throw new Error('Reported an error');//rejected }).then(result => result) Promise.allSettled([p5, p6]) .then(result => console.log(result)) .catch(e => console.log(e));

Promise.race()
This method also packs multiple Promise instances into a new Promise instance. The other features are similar to all. The difference with all is: the race method is like a race. If several instances run together, whoever arrives first will succeed. Whoever resolves, or who ran to the midway and fell into an abnormal situation and failed, reject whoever, regardless of success or failure, first capture the first completed.
- Capture the first successful instance callback function
let p1 = Promise.resolve('1') let p2 = Promise.resolve('2') Promise.race([p1,p2]).then(res=>conseloe.log(res)) //OUTPUT: '1'
- Capture the first result
let p1 = Promise.resolve("1"); let p2 = Promise.reject("ERR2"); Promise.race([p1,p2]).then(res=>console.log(res)) //OUTPUT: Promise {<resolved>: "1"}
- Catch the first error
let p1 = Promise.reject("ERR1"); let p2 = Promise.reject("ERR2"); Promise.race([p1,p2]).catch(console.log) //OUTPUT: Promise {<reject>: "ERR1"}
- The design principle of native implementation of Promise.race()
Promise._race = iterator =>{ return new Promise((resolve,reject)=>{ iterator.forEach(item=>{ Promise.resolve(item).then(resolve).catch(reject) }) }) }
Promise.try
In the actual development and use of promises, it is hoped that the internal code of the function wrapped by the promise will allow the synchronous function to be executed synchronously, and the asynchronous function will be executed asynchronously
let fn = () =>console.log('Sync 1'); Promise.resolve().then(fn) console.log('Sync 2') //OUTPUT: //'Sync 2' //'Sync 1'
- Application of Promise.try
This method is used to simulate
Try catch in JavaScript is exception handling mechanism. The code that may be wrong is placed in the try statement block. If there is an error, it will be caught by catch to handle the exception. If you don't catch an error, it will cause the program to crash. finally : Regardless of the result, it is allowed to execute code after try and catch .
try { // code block for testing } catch(err){ //Code block for handling errors } finally { //code block to be executed regardless of the result of try/catch }
- application
let fn = () => console.log('Sync 1'); Promise.try(fn); console.log('Sync 2'); //'Sync 1' //'Sync 2'
Solve the current method of letting synchronous functions execute synchronously and asynchronous functions asynchronously execute
- Method 1: Using the async anonymous function, the async function inside will be executed immediately, so if fn is synchronous, you will get a synchronous result; if fn is asynchronous, you can use then to specify the next step, if you want to catch errors, use catch method.
let fn=()=>console.log('Sync 1'); (async ()=>fn())() .then(resolve) .catch(err=>console.log(err)) console.log('Sync 2') //After log //'Sync 1' //'Sync 2'
- Method two: use the anonymous function that promises to execute immediately
let fn=()=>console.log('sync 1'); (()=>new Promise( resolve => resolve(fn()) ))() console.log('sync 2') // log after // 'sync 1' // 'sync 2'
Hope you like our “Javascript Promises in Depth” blog. Please subscribe to our blog for upcoming blogs.
Happy Coding!
What’s up friends, good article and pleasant arguments commented at this place, I am really enjoying by these.
Thank You
Very nice article. Clears all concepts about promises.
Thank You
A motivating discussion is definitely worth comment. I do believe that you should write more on this topic, it might not be a taboo matter but generally people do not talk about such subjects. To the next! Many thanks!! coca cola gravid
Sure
Discover the best ever for free!
Im very happy to find this web site. I want to to thank you for ones time just for this fantastic read!! I definitely appreciated every part of it and i also have you saved as a favorite to see new information in your blog.
I must thank you for the efforts youve put in penning this site. I am hoping to check out the same high-grade blog posts by you in the future as well. In fact, your creative writing abilities has motivated me to get my very own blog now 😉