๐ Prerequisites
- Basics of JavaScript
๐ค What is the promise in JavaScript?
The promise is the object we used for the asynchronous task. it gives us the idea that either our asynchronous task is successful or failed.
The promise has 3 states:
- Pending: This is the initial state, which means neither fulfilled nor rejected.
- Fulfilled: This means the promise was resolved successfully.
- Rejected: This means the promise failed.
๐ค How to create promise?
The syntax to create promise is:
const promise = new Promise((resolve, reject) => {
// Do some logic
})
The arguments resolve
and reject
are the callbacks provided by JavaScript itself.
resolve(value): The
resolve
is called when the request is successful with a value as a result.reject(error): The
reject
is called when the request is failed with the error as a result.
The object returned by new Promise
has these properties:
state: this is "pending" initially, when
resolve
is called it will change to "fulfilled", and whenreject
is called it will change to "rejected".result: this is
undefined
initially, whenresolve(value)
is called it will change tovalue
, and whenreject(error)
is called it will change toerror
.
๐ค How to use promise?
We can consume Promise by using the methods .then
, .catch
, and .finally
.
1. .then
The syntax of .then
is:
promise.then(
(result) => {/* use the result when promise success */ },
(error) => { /* show error if promise rejected */ }
)
The first argument of .then
is called when the promise is in a fulfilled
state with result
as value.
The second argument of .then
is called when the promise is in a rejected
state with an error
as value.
For example:
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Done"), 3000);
})
promise.then(
(result) => console.log(result), // log Done after 3 sec
(error) => console.log(error) //doesn't run
)
And
const promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Damn error")), 3000);
})
promise.then(
(result) => console.log(result), //doesn't run
(error) => console.log(error) // logs Damn error after 3 sec
)
If we want to handle just the result value we can use a single argument, like:
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Done"), 3000);
})
promise.then((result) => console.log(result)) // log Done after 3 sec
2. .catch
As we have seen. .then
will show both the result as well as the error. but what if we only want to deal with errors.
We can either use:
const promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Damn error")), 3000);
})
promise.then(null,
(error) => console.log(error) // logs Damn error after 3 sec
)
Or we can use .catch
const promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Damn error")), 3000);
})
promise.catch((error) => console.log(error)) // logs Damn error after 3 sec
3. .finally
We can use .finally
when we have to execute some code even if the promise is either resolved or rejected. e.g. like stoping the loading spinner
const promise = new Promise((resolve, reject) => {
// Do some logic
})
promise.finally(() => stop loading spinner);
๐คฏ Different promise methods
1. Promise.all()
The Promise.all()
will take the array of promises as an input and return the Promise
that resolves to an array of results in the same order as the input promises, if all the promises are fulfilled
.
Even if the single promise is rejected
, the resulting promise will reject and it will give the error/message.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 3000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(2), 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => resolve(3), 1000);
});
Promise.all([ promise1 , promise2 , promise3 ]).then(values => {
console.log(values); // [1, 2, 3]
});*
As you can see, even if the promise3 resolves early it will give the result at last. As it depends on the order in which you called the promises.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 3000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => reject(2), 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => resolve(3), 1000);
});
Promise.all([ promise1 , promise2 , promise3 ]).then(values => {
console.log(values);
}).catch(e => {
console.log(e) // 2
})
We can use Promise.all()
when we have a series of asynchronous tasks which are dependent on one another.
2. Promise.allSettled()
The Promise.allSettled()
will take the array of promises as an argument and return the Promise
which resolves even if the input promises are fulfilled or rejected.
We can use Promise.allSettled()
when we have a series of asynchronous tasks which are independent of one another.
Promise.allSettled([
new Promise(resolve => setTimeout(() => resolve(33), 1000)),
new Promise(resolve => setTimeout(() => resolve(66), 0)),
99,
Promise.reject(new Error('an error'))
])
.then(values => console.log(values));
// [
// {status: "fulfilled", value: 33},
// {status: "fulfilled", value: 66},
// {status: "fulfilled", value: 99},
// {status: "rejected", reason: Error: an error}
// ]
If the Promise
is resolved it will give the status: "fulfilled"
and the value
with the resolved value.
And if Promise
is rejected it will give the status: "rejected"
and the reason
with the error message.
3. Promise.any()
Promise.any()
takes the array of promises as an input and it will return the resolved Promise
as soon as one of the input promises is resolved.
And if all the input promises are rejected, it will return the error as AggregateError
.
Promise.any([
new Promise(resolve => setTimeout(() => resolve(33), 1000)),
new Promise(resolve => setTimeout(() => resolve(66), 100)),
Promise.reject(new Error('an error'))
])
.then(values => console.log(values)); //66
Promise.any([
Promise.reject(new Error('an error1')),
Promise.reject(new Error('an error'))
])
.then(values => console.log(values))
.catch(error => console.log(error)) // "AggregateError: No Promise in Promise.any was resolved"
4. Promise.race()
The Promise.race()
will take the array of promises as an input and return the Promise
which is either fulfilled or rejected, if one of the input promises is fulfilled or rejected.
Basically, It will return the first promise which is either fulfilled or rejected.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(33), 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(66), 2000);
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise1 is faster
});
// expected output: 33
๐ค References
That's it!๐คฉ I hope you got some clarity about promises.
Thanks for reading ๐ค