Okay! So before starting we'll make a promise to each other ๐
My Promise: I'll try to explain Javascript Promises, in the best way possible! ๐
Your Promise: Read the complete blog! ๐
For now, both of our promises are in a pending state, let's try to get them fulfilled ๐
Okay, We'll start with a small introduction of asynchronous JS
Asynchronous Javascript
We know that Javascript is a single threaded
i.e Only one thing can happen at a time, on a single main thread, and everything else is blocked until an operation completes.
So, Suppose if you want to fetch data from the network or database, main thread
will get blocked and how much time it will take to complete we don't know.
Hence, to solve this problem we have two main types of asynchronous code style:
- Old-style callbacks
- Newer promise-style code
We'll explore each one of it!
Callback
Let's understand it with an example ...
vanilla JS
example
const btn = document.querySelector('button')
btn.addEventListener('click', () => {
console.log('That might sound boring, but I think the boring stuff is the stuff I remember the
most.')
} )
Explanation: Here, the first argument is a type of event
and the second is parameter is a callback
function that is invoked when the event is fired.
React JS
example
const printMessage = () => {
console.log('That might sound boring, but I think the boring stuff is the stuff I remember the
most.')
}
<button onClick={printMessage}>Message</button>
Here, also printMessage
is a callback function i.e executed when click
happens!
Note: Not all callbacks are async โ some run synchronously.
For example:
const upCharacters = ['Russell', 'Carl Fredricksen', 'Ellie Fredricksen', 'Kevin', 'Dug'];
upCharacters.forEach((name) => {
console.log(name)
} );
Okay, now let's start with promises...
Promises
Promises are the new style of async code
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Promise has 3 states:
- Pending
- Fulfilled
- Rejected
Example
const callbackFunctionofSuccess = () => {
console.log('Data is Fetched Successfully')
}
const callbackFunctionofFailure = () => {
console.log('Something went wrong')
}
fetch('url').then(callbackFunctionofSuccess).catch(callbackFunctionofFailure)
fetch()
takes URL and returns a Promise
. To resolve a promise we have, .then
which takes a callbackFunctionofSuccess
that executes if the promise is fulfilled, whereas if the promise is rejected .catch()
block is executed.
Promise Chaining
If we want to execute two or more asynchronous operations back to back, where each requires a previous operation result then chaining
comes in!
Example
chooseMovie()
.then(up =>
selectMovie(up)
)
.then(watch =>
watchMovie(watch)
)
.then(liked =>
likedMovie(liked)
)
.catch(failureCallback);
To avoid promise chaining
and to write clean code, we have async
& await
Async Await
Async Await acts as syntactic sugar on top of promises, making asynchronous code easier to write and read!
const fetchData = async() => {
try{
const response = await fetch(URL)
console.log(response)
}
catch(err){
console.log(err)
}
}
Yes, Async Await
are simple and easy to understand
Promise Constructor - Go Deep!
- To write a promise
const youSayYes = true
const downloadMovie = new Promise((resolve, reject) => {
if(youSayYes){
resolve('Movie Downloaded')
}
else {
reject('Something went wrong')
}
})
- To consume a promise
downloadMovie.then((d) => console.log(d)).catch((err) => console.log(err))
Yes, so the output will be Movie Downloaded
Static Methods of Promise
Promise.all(iterable)
Promise.race(iterable)
Promise.reject(reason)
Promise.resolve(value)
Instance Methods of Promise
Promise.prototype.then()
Promise.prototype.catch()
Promise.prototype.finally()
Promise.all()
Promise.all()
method takes an iterable of promises as an input and returns a single Promise that resolves to an array of the results of the input promises. It rejects immediately upon any of the input promises rejects.
const promise1 = Promise.resolve(10);
const promise2 = 20;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 30);
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// expected output: Array [10,20,30]
Promise.race()
Promise.race()
also accepts an array of promises but returns the first promise that is settled. A settled promise can either be resolved or rejected.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
Yes, so promise2
resolves faster, therefore output will be two
Congratulations
Finally, we reached our destination. Since you are here, you fulfilled your promise and I hope I was able to keep mine too.
Hope you enjoyed and learnt something new! Bye ๐