This post is second part of the previous one. If you haven't read it yet, read it here:
In this article, we are going to learn about promises and the new & improved/alternate way to achieve asynchronous task using async/await
instead of promise.
The objectives are to learn following:
Promise
Promise.prototype.finally
async/await
for...await...of
Promise: An Introduction
So, what is promise?
It is an object, which guarantees us to return a single value some time in future for an asynchronous operation.
Let's understand it a bit more by understanding the states that a promise can have. A promise is an object (mentioned above) can have 3 states:
- fulfilled: When promise is resolved/fulfilled.
- rejected: When a promise failed to get fulfilled.
- pending: Neither rejected not fulfilled is the pending state.
Now here is the syntax on how to write a promise in javascript:
An explanation on above code.
- Line 2: We are creating/constructing a promise object. state would be pending and result will undefined
-
Line 7: Promise is getting resolved here so the state would be fulfilled with a returned value of the string inside
resolve
. - Line 10: Promise is getting rejected here. The state would be rejected and sets the result to error with the error value provided.
Now, we can use the promise
object as shown below:
promise.then(
success => console.log(success),
error => console.log(error)
);
So, promise provides then
-ability which is what guarantees us to get the data once a promise is resolved/rejected.
Finally, we can derive some rules regards to Promise
:
- A promise provides
then()
method. - A pending promise can result to either 'fulfilled' or 'rejected' state
- A fulfilled or rejected promise is considered as settled. So, it must not transition to any other state.
- Once a promise is settled, it should have a value which must not change.
A bit more on then
is needed. Right? Ok, let's first look at the syntax of then
:
promise.then(onFulfilled[, onRejected]);
-
onFulfilled
: Callback for resolved/fulfilled promise -
onRejected
(optional): Callback for rejected promise
One of the great thing about promise is chaining
To achieve the chaining, we use then()
method provided by promise. Let's have a look at following example.
const promise1 = promiseOne()
const promise2 = promise1.then(onFulfilled, onRejected)
// OR
const promise = promiseOne().then(onFulfilled, onRejected)
So, each promise represents the completion of another asynchronous step in the chain.
Before promise arrived, we fall in a classic callback pyramid of doom trap. Let's have a look:
But, with promise, we use the callback on returned promise instead to form the promise chain which makes code better and more readable.
catch
looks new here, right? Ok. so catch is another method provided by promise which catches any kind of error that might have happened while promise tries to fulfil.
It is completely possible to chain after
catch
usingthen
.
Promise.prototype.finally
This is again part of promise Promise.prototype.finally
. It is useful when we wants to execute some sort of code regardless the outcome of the promise (be it fulfilled or rejected). Syntax is given below.
Let's move to our next point which is async/await
async/await
async/await
is nothing more than syntactic sugar for promises that we learnt above. Let's look at the syntax first:
Let's say we need to fetch json file from a url. Here is how we will write it using promise
.
const getJson = url => fetch(url).then(json => console.log(json))
// call the getJson method
getJson('https://jsonplaceholder.typicode.com/todos/1')
Now, let's have a look on how we can use async/await
for this.
Both implementation are doing the same thing but async/await
is more readable. As I have mentioned before about chaining, promise/then
makes code less readable when we start doing the chaining but with async/await
, you get more neat and clean code. Example given below to explain it. Here, I have created three promises:
Now have a look at the usage of promise and async/await
The promise
way
The async/await
way:
So, which one you prefer. Let me know in the comment section. Personally, I like async/await
. It makes code more readable in synchronous way which leads to more manageable code.
Tip:
await
can only be used insideasync
function.
Go ahead and do practice this at your own. Have questions, feel free to drop a comment with your question.
for...await...of
This one is related to await
that we learnt just now. This helps us to iterate over async iterable objects as well as on sync iterables which includes built in string, array or array like objects (eg. arguments
). Syntax:
for await (let item of iterable) {
// code goes here...
}
Let's take an example. Suppose, we need to fetch data from 3 urls. The urls are stored in an array.
I am sure you also realise how clean it is and how useful it can be. So, practice, practice and practice.
Summary
Today we learnt about Promise
. The newer and nicer way to use the Promise
by using async/await
. We also looked at finally
along with how to iterate on await
using for...await...of
. Some of the terminology to remember are:
- Promise
- resolve/fulfilled
- reject
- settled
- chaining
- then
- catch
- finally
- async
- await
- for...await...of
There are chances that you have questions around some of the points above which is not explained. It is kind of done intentionally so that you can come up with questions and also start exploring at your own. For any questions, drop a comment and own awesome community folks or myself will help you to get it answered.
Here are two questions from me for you to answer.
Q1: How to use multiple promises in parallel?
Q2: How can we solve
Q1
withasync/await
Thanks for reading. Happy learning.
--
Originally published at https://elanandkumar.com/blog/es6-and-beyond-II
Top comments (0)