Beginners guide to Promises in JavaScript
Simplifying one of the complicated Js fundamentals that's actually very simple !
π€ What are Promises ?
Promises in JavaScript though overwhelming to look up on the Internet, but actually works like Promises in our daily lives.
For example,
Vikas makes a 'promise' to his friend Rajesh, to pick him up from the airport.
Now, there can be two possibilities,- Either Vikas fulfills the promise and picks him up.
- Vikas doesn't pick him up due to some problems, thus rejects the promise but notifies Rajesh. He books a Cab then.
In programming world, a Promise is a proxy for a value not necessarily known at the time when the promise is created. The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
In JavaScript, the syntax goes like,
let promise = new Promise(function(resolve, reject) { //some code here... }); //using ES6 arrow functions, let promise = new Promise((resolve, reject) => { //some code here... });
The function passed to
new Promise
is called the executor. When new Promise is created, the executor runs automatically.
Its argumentsresolve
andreject
are callbacks provided by JavaScript itself. Our code is only inside the executor.When the executor obtains the result, be it soon or late, doesnβt matter, it should call one of these callbacks:
- resolve(value) β if the job is finished successfully, with result value.
- reject(error) β if an error has occurred, error is the error object.
A Promise object serves as a link between the executor function and the consuming functions (functions or code that deals with the 'outcome' of the promise), which will receive the result or error. This is done through methods like
.then
and.catch
.Let's understand this with an example,
let finishedWritingMyBlog = true; let myPromise = new Promise((resolve, reject) => { if(finishedWritingMyBlog){ resolve({ message : 'Cheers, its done !!!' }); } else { reject({ name : 'Still Writing', message : 'Not Done !' }); } }); myPromise.then((msg) => { console.log(msg); }) .catch((error) => { console.log(error.name + ' : ' + error.message); });
π€ Do we need Promises, if we have callbacks()
?
Promises can replace callbacks, but they are not callbacks. In fact, Promises are more than just callbacks. They are a very mighty abstraction, allow cleaner and better, functional code with less error-prone boilerplate.
Promises allow us to do things in the natural order. First, we run the script, and then we write what to do with the result. Where as in Callbacks, we must know what to do with the result when the scripts are run.
We can call
.then
on a promise multiple times. But, there can be only one callback.
π€ Chaining in Promises
- Promises allows us to perform a sequence of asynchronous tasks to be performed one after the other.
new Promise((resolve, reject) => { setTimeout(() => resolve(1), 1000); }) .then((result) => { alert(result); // 1 return result * 2; }) .then((result) => { alert(result); // 2 return result * 2; }) .then((result) => { alert(result); // 4 return result * 2; });
π€ Promises API
- Promise.all()
Promise.all
allows us to run multiple promises in parallel and wait until all of them are ready. - Promise.race()
Promise.race()
returns as soon as we have a 'result' or one promise is settled. - Promise.any()
Promise.any()
returns as soon as we have a 'resolved result' or one promise is fulfilled. let promiseOne = new Promise((resolve, reject) => { setTimeout(() => resolve('First Done'), 2000) }); let promiseTwo = new Promise((resolve, reject) => { setTimeout(() => resolve('Second Done'), 1000) }); let promiseThree = new Promise((resolve, reject) => { setTimeout(() => resolve('Third Done'), 4000) });
Promise.all([ promiseOne, promiseTwo, promiseThree ]) .then((messages) => { console.log(messages); }); //returns an array of messages
Promise.race([ promiseOne, promiseTwo, promiseThree ]) .then((message) => { console.log(message); }); //Second Done //Since, second one is settled quickly after 1sec.
let promiseOne = new Promise((resolve, reject) => { setTimeout(() => resolve('First Done'), 2000) }); let promiseTwo = new Promise((resolve, reject) => { setTimeout(() => reject('Error Here in Second'), 1000) }); Promise.any([ promiseOne, promiseTwo, promiseThree ]) .then((message) => { console.log(message); }); //First Done //Even though the second is settled first, but it's not resolved. //So, the first one is logged.
π€ Async/await
These are a kind of special syntax to work with promises.
async
keyword before a function means it returns a promise.async function foo() { return 'Hello World'; } foo().then(msg => console.log(msg)); //Hello World
await
keyword is used insideasync
functions. It makes JavaScript wait until that promise settles and returns its result.async function foo() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("Hey There"), 1000) }); let result = await promise; return result; } foo().then(msg => console.log(msg)); //Hey There
π Conclusion
That's all about Promises to get started. They are extremely important for asynchronous calls for APIs where its extensively used.
Thanks for staying till the end ! Hope you have enjoyed it so far...
Here are some good documentations to read more about it.
MDN Docs : Promises
JavaScript Info : 11.1 - 11.8
Some good videos to get you started,