You look at someone´s other code and aks yourself how the fuck am I supposed to understand what he is doing with all those Promises chaning. You wonder how can that be done better and most of all better to read but also understand. Async/Await is here to save the day for you. Async/Await is a special syntax which makes working with promises more comfort it´s simply avoiding Promise chaning and it´s surprisingly easy to understand and use.
Async Keyword/Function
Now let´s move on and declare how we should use the syntax of Async/Await starting with the keyword async
it can be placed before a function, like this. It works with the normal function´s but also with Arrow function´s.
1 2 3 4 5 6 7 8 9 |
// Returns a resolved Promise with a value of '1' const modevAsync = async function () { return 1; }; // Arrow Function - Returns a resolved Promise with a value of '1' const modevArrowAsync = async () => { return 1; }; |
The keyword async
before a function simply means: this function is always returning a Promise. So let´s test out one of the above created functions. I´ll go on with the function modevArrowAsync
:
1 2 3 4 5 6 7 8 9 |
// Arrow Function - Returns a resolved Promise with a value of '1' const modevArrowAsync = async () => { return 1; }; modevArrowAsync() .then( ( value ) => { console.log( value ); // 1 }); |
We can append a .then
on the function call because as we now know the async
keyword before the function always returns a Promise. Let´s move on with the other keyword await
that works only inside async
functions.
Await Keyword
This keyword can only be used inside a function with is declared as async
. What this keyword simply does -> it makes javascript wait until that promise is finished and returns its result.
The syntax:
1 2 |
// Only inside async functions let value = await promise |
Example of the functionality of await.
1 2 3 4 5 6 7 8 9 10 11 |
// Arrow Function const modevArrowAsync = async () => { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("New Blog Post!"), 1000) }); let value = await returnPromise( true ); // wait till the promise finshied and gets the String console.log( value ) // "New Blog Post!"" }; |
Fucntion call with await
waits until the promise is finshed and then goes on with the code underneath. Remember await can only be uses in function with declared with the keyword async
. So now let´s dive into a real world example. First I´m showing you the function without Async/Await.
This is the function without the keywords.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// No async keyword const convertCurrency = ( from, to, amount ) => { // We need to declare this variable because 'getCountries' does not have acces for the values in the first Promise let convertedAmount; // Promise1 return getExchangeRate( from , to ) .then( ( rate ) => { // Value we need in the second Promise convertedAmount = (amount * rate).toFixed( 2 ); // Promise2 return getCountries( to ) .then( ( countries ) => { // Values from Parameter, Promise1 and Promise2 return `${amount} ${from} is worth ${convertedAmount} ${to}. You can spend it in the following countries: ${countries.join(', ')}` }) }); }; |
Now with the Keywords watch how easy it get´s to read the code in contrast to the example above.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const convertCurrency = async ( from, to, amount ) => { // Promise1 // Waits until API calls is finshed and stores the result in variable rate const rate = await getExchangeRate( from, to ); // Some calculation with the new value from Promise1 let convertedAmount = (amount * rate).toFixed( 2 ); // Promise2 // Waits until API call is finished and stores the result in variable countries const countries = await getCountries( to ); // Now we have acces to all variables declared from Parameter, Promise1, Promise2 return `${amount} ${from} is worth ${convertedAmount} ${to}. You can spend it in the following countries: ${countries.join(', ')}` }; |
Isn´t that easy to read? Much better than before.
Error handling
In case of rejection it throws the error, just if there is a throw
statement in that line. So no need the explicit call reject
but it does also work.
For example this code:
1 2 3 |
async function modevErrorHandling() { await Promise.reject(new Error('This is an Error!')) } |
Is completly the same as:
1 2 3 |
async function modevErrorHandling() { throw new Error("This is also an Error!"); } |
Now some real world examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const getExchangeRate = async ( from, to ) => { try { // Request to API - waits until call is finished const response = await axios.get('http://data.fixer.io/api/latest?access_key=3e6cda999e4c0b20785bf449e38ca2da'); // Some calculations const euro = 1 / response.data.rates[from]; const rate = euro * response.data.rates[to]; if ( isNaN( rate ) ) { // This Error gets thrown when rate is not a number throw new Error('Rate is not a number'); } return rate }catch (e) { // This Error gets throw when something went wrong with the API call throw new Error(`Unable to get exchange rate for ${from} and ${to}.`) } }; |
With try
and catch
we can easily throw an Error if something goes wrong with the API call. The await
keyword cause that javascript needs to wait until the call to the API is finished. After that we are doing some calculation with the response from the API. After that we check if rate
is a number, if not we throw an Error and the Promise gets rejected. The catch block catches an Error if something went wrong in the try block -> For example the API call went wrong.
Conclusion
The async keyword before a function has two effects:
- Makes it always return a promise.
- Allows to use await in it.
The await
keyword before a promise makes JavaScript wait until that promise settles, and then:
If it’s an error, the exception is generated, same as if throw error were called at that very place.
Otherwise, it returns the result, so we can assign it to a value.
Together they provide a great framework to write asynchronous code that is easy both to read and write.
You now have an brief overview how to use Async and Await keywords. All the examples in this blog post have been showing examples, which is more than enough to begin with. If you want to take a look at other article I wrote feel free to visit my blog.
Hope you guys and girls enjoyed reading this as much as I enjoyed writing it. Do you think this tutorial will be of help to someone? Do not hesitate to share. If you liked it, share it somewhere else or subscribe to my blog.