-
Notifications
You must be signed in to change notification settings - Fork 0
26 Promises
Biswajit Sundara edited this page Aug 18, 2023
·
1 revision
Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
- It is a way to handle asynchronous code in a more structured and manageable manner.
- Promise will ensure that control doesn't move to the next operation until the current one is resolved or rejected.
- This behavior allows you to synchronize asynchronous code
- The execution will wait until the Promise settles, either by being fulfilled or rejected.
- And the execution will not move further until the promise is resolved.
Execute the below code in a browser so we can see how it works under the hood.
- The initial state when a Promise is created, representing that the asynchronous operation is still in progress
- and the final value is not yet available.
const output = new Promise((resolve, reject)=>{
});
console.log(output);
/*
This will print this way
[prototype]: Promise
[promiseState]: Pending
[PromiseResult]: undefined
*/- The state that represents a successful completion of the asynchronous operation.
- In this state, the Promise has a resolved value associated with it.
const output = new Promise((resolve, reject)=>{
resolve('Hello')
});
console.log(output);
/*
This will print this way
[prototype]: Promise
[promiseState]: fulfilled
[PromiseResult]: Hello
*/- The state that represents a failure or error during the asynchronous operation.
- In this state, the Promise has a reason or error associated with it.
const output = new Promise((resolve, reject)=>{
reject('Oops the server encountered an error')
});
console.log(output);
/*
This will print this way
[prototype]: Promise
[promiseState]: rejected
[PromiseResult]: Oops the server encountered an error
*/If we take an real world example, sending a http request to the server then it will end up in any of the below states
-
Success (Fulfilled)- If we get the data back from the server -
Error (Rejected)- Oops the server encountered an error -
Pending- The server couldn't fetch the data with the specified time
const fetchData = () =>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
let data = { message: 'Data retrieved successfully' };
resolve(data);
}, 2000);
setTimeout(()=>{
// Reject the Promise with an error
reject("Error while getting data from the server");
},5000);
})
}
fetchData()
.then((result)=>{
console.log(result);
})
.catch((error)=>{
console.log(error);
})- If we run above code. It will print the message
Data is retrieved successfullybecause it returns the value in 2s. - To check the error step, if we decrease the time out value to 1000 from 5000 then it will be executed first
- and then it will print the message
Error while getting.. - The promise state will be either fulfilled or pending and it can't be both.
- note, once the promise object is returned, there's no further processing.
- If the promise is fulfilled then we can use
.then()to extract the value - and if it's rejected then we can use
.catch()to catch the error. - The
.then()method is used to handle the promise, it accepts a callback function that will be executed when the Promise is fulfilled. - We can chain multiple .then() calls to handle the Promise's resolved value.
- we can use the .catch() method to handle any errors that may occur during the Promise's execution.
- If the Promise is rejected (by calling reject in the executor function or if an error occurs), the
.catch()callback will be executed. - We can also have
finallymethod, if we have something to execute in both fulfilled/rejected state.
fetchData()
.then((result)=>{
console.log(result);
})
.catch((error)=>{
console.log(error);
})
.finally(()=>{
console.log('Finally');
})- Let’s say we want many promises to execute in parallel and wait until all of them are ready.
- For instance, download several URLs in parallel and process the content once they are all done.
Syntax: let promise = Promise.all([...promises...]);
- Promise.all takes an array of promises and returns a new promise.
- The new promise resolves when all listed promises are settled, and the array of their results becomes its result.
- If we reduce the time out in the reject block in any one of the promises,
- it will fail the entire thing and the
promise.allwill return the error object
const promiseNames = new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve(["Kangna","Kapil","Kajol"]);
},3000);
setTimeout(()=>{
reject("Error while getting data from the server");
},5000);
});
const promiseSurnames = new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve(["Ranaut","Sharma","Mukherjee"]);
},3000);
setTimeout(()=>{
reject("Error while getting data from the server");
},5000);
});
Promise.all([promiseNames,promiseSurnames]).then((data)=>{
//Simply print the arrays
console.log(data);
//Use destructuring
const [names, surnames] = data;
for (let i=0;i<names.length; i++){
const name = names[i];
const surname = surnames[i];
console.log(`${name} ${surname}`);
}
}).catch((error)=>{
console.log(error);
})- To make the calls sequential we can do method chaining and using
thenwe can extract values from promises.
const getRandomUsers = ((numberOfUsers)=>{
const fetchUsers = fetch(`https://randomuser.me/api/?results=${numberOfUsers}`);
console.log(fetchUsers);
fetchUsers.then((response)=>{
response.json().then((randomusers)=>{
console.log(JSON.stringify(randomusers));
console.log(JSON.stringify(randomusers.results.length));
randomusers.results.array.forEach(user => {
const {gender, email} = user;
console.log(`${gender} ${email}`);
});
})
})
})
getRandomUsers(5);- We can do promise chaining using the
thenoperator - While forming a promise chain make sure to return the promise like
return proceedToPayment(orderId);
const cart = ['Milk','Fruits','Veg'];
const createOrder = (cart) =>{
const promise = new Promise((resolve)=>{
resolve("123");
})
return promise;
}
const proceedToPayment = (orderId) =>{
return new Promise((resolve, reject)=>{
if(orderId){
resolve("pay 500$");
}
})
}
const makePayment = (paymentInfo) =>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve("Payment Successful");
},2000);
})
}
createOrder(cart)
.then((orderId)=>{
console.log(orderId);
return orderId;
})
.then((orderId)=>{
return proceedToPayment(orderId);
})
.then((paymentInfo)=>{
return makePayment(paymentInfo);
})
.then((paymentStatus)=>{
console.log(paymentStatus);
})
.catch((error)=>{
console.log(error);
})- To handle the errors we have
catchmethod. - If we write it at the last then if any of the method fails in the chain it will abort
- If we want to handle the error for a specific method, have it just after the
thenblock - We can have the
catchblock after everythenblock also in the chain.
- A Promise can be created using the Promise constructor, which takes a function (commonly referred to as the executor function) as an argument.
- The executor function receives two parameters:
resolveandreject. - Within the executor function, we perform the asynchronous operation and use resolve to fulfill the Promise
- with a value or reject to reject it with an error.