What is a Promise?
Promises are used to handle asynchronous operations introduced in ES6
. It is an object that represents the eventual completion or failure of an asynchronous operation.
They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code. Callback functions were used before promises, but they had limited functionality and resulted in unmanageable code. The nightmare that would result from having several callback functions would make the code unmanageable.
Create a Promise
A promise is created using the new
keyword, and it takes a function as an argument. This function takes two parameters, resolve
and reject
. The resolve
function is called when the asynchronous operation is successful, and the reject
function is called when the asynchronous operation fails.
const promiseFunction = () => {
new Promise((resolve, reject) => {
// do something
if (everythingIsOk) {
resolve("success");
} else {
reject("failure");
}
});
};
How to use a Promise?
A promise is used by calling the then()
method on the promise object. The then()
method takes two functions as arguments, the first function is called when the promise is resolved, and the second function is called when the promise is rejected.
promiseFunction()
.then((result) => {
// if everyThingIsOK, and promise is resolved, then this function is called
})
.catch((error) => {
// if something went wrong, and promise is rejected, then this function is called
});
States of a Promise
A promise (in JS context) takes some time to execute. There are possible states
of a promise:
-
fulfilled
✅: Action related to the promise succeeded -
rejected
❌: Action related to the promise failed -
pending
⏳: Promise is still pending i.e. not fulfilled or rejected yet
As promise takes in two functions as parameters. That is, resolve
and reject
in declaring it.
Here is an example of a promise:
const myPromise = new Promise((resolve, reject) => { // resolve and reject are functions
if (/* condition */) {
resolve("Promise was fulfilled ✅");
} else {
reject("Promise was rejected ❌");
}
});
The resolve
function is called when the promise is fulfilled and the reject
function is called when the promise is rejected. The resolve
and reject
functions are called inside the promise. The resolve
and reject
functions are passed as parameters to the promise.
The then()
method is used to handle the promise. It takes two functions as parameters. The first function is called when the promise is fulfilled ✅. The second function is called when the promise is rejected ❌.
myPromise
// highlight-start
.then((value) => {
console.log(value);
})
// highlight-end
.catch((error) => {
console.log(error);
});
The catch()
method is used to handle the promise when it is rejected ❌. It takes a function as a parameter. The function is called when the promise is rejected.
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
});
Examples
Return a random number between 1 and 10
Let's create a promise that will return a random number between 1 and 10. If the number is greater than 5, the promise will be resolved, and if the number is less than 5, the promise will be rejected.
const randomNumberGenerator = () => {
new Promise((resolve, reject) => {
const randomNumber = Math.floor(Math.random() * 10) + 1;
if (randomNumber > 5) {
resolve(randomNumber);
} else {
reject(randomNumber);
}
});
};
randomNumberGenerator()
.then((result) => {
console.log(`Success: ${result}`);
})
.catch((error) => {
console.log(`Error: ${error}`);
});
Fetching Data from an API using Promises
function getData() {
return new Promise((resolve, reject) => {
fetch("https://jsonplaceholder.typicode.com/todos/1")
// Data will be assigned to the variable `response`, if the promise is fulfilled
.then((response) => response.json())
// ☝️ here we are converting the response to JSON, and returning it to the next `then` function
.then((data) => resolve(data))
// ☝️ here we are resolving the promise with the data
.catch((error) => reject(error));
// ☝️ here we are rejecting the promise with the error
});
}
// Calling the function `getData`
getData()
// 👇 `then()` will be called if the promise is resolved
.then((data) => {
console.log(data);
})
// 👇 `catch()` will be called if the promise is rejected
.catch((error) => {
console.log(error);
});
In the above example, getData()
is a function that returns a promise. It fetches the data from the API. The then()
method is used to handle the promise when it is fulfilled. The catch()
method is used to handle the promise when it is rejected.
Promise Chaining
Promise chaining is a way to handle multiple promises. It is used to handle asynchronous operations in a better way. It is a replacement for callbacks and events. It is used to handle asynchronous operations in JavaScript, such as making HTTP requests to a server, reading from a file, or interacting with a database. They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code. Callback functions were used before promises, but they had limited functionality and resulted in unmanageable code. The nightmare that would result from having several callback functions would make the code unmanageable.
const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise 2 resolved");
}, 2000);
});
promise1
.then((value) => {
// `value` will be "Promise 1 resolved"
console.log(value);
return promise2; // returning the `promise2` to the next `then` function
})
.then((value) => {
// `value` will be "Promise 2 resolved"
console.log(value);
})
.catch((error) => {
console.log(error);
});
In the above example, the promise1
is resolved first. Then the promise2
is resolved after 2 seconds. The then()
method is used to handle the promise when it is fulfilled. The catch()
method is used to handle the promise when it is rejected.
Promise.all()
It takes an array of promises as an argument. It returns a single promise. It resolves when all of the promises in the argument array have resolved. It rejects with the reason of the first promise that rejects.
const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise 2 resolved");
}, 2000);
});
Promise.all([promise1, promise2])
.then((values) => {
console.log(values);
})
.catch((error) => {
console.log(error);
});
Promise.allSettled()
It returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise 2 resolved");
}, 2000);
});
Promise.allSettled([promise1, promise2])
.then((values) => {
console.log(values);
})
.catch((error) => {
console.log(error);
});
Conclusion
Here we have learned about promises in JavaScript. We have learned about the Promise
object, the then()
method, the catch()
method, promise chaining, Promise.all()
, and Promise.allSettled()
. We have also learned about the examples of promises in JavaScript.
Top comments (0)