by Indrek Lasn
await syntax somewhere.
Async/await is arguably one of the best-received new additions to the language. Async/await makes asynchronous code appear and behave like synchronous code. Async/await are promise-based.
Before we jump into async/await, we must understand what are promises and the role they play.
Note; This article was originally published under strilliant.com
Promise is an object representing the eventual completion or failure of an asynchronous operation.
Why do we need asynchronous code, anyway?
What are callbacks?
You might have seen jQuery specific code like this.
The following code attaches an event listener on our button and calls the
alert once it’s triggered.
Where is the callback? Can you tell?
You probably can — it’s the anonymous
function inside the
click function parentheses.
Callbacks in a nutshell: we trigger a function, do some stuff, then call another function.
Callbacks are not all bad, they worked — they still do. But, what happens if we have a callback inside a callback inside a callback — you get the point. It gets really messy and unmaintainable really quick.
This problem above is named “callback hell.”
One more example to seal the case for callbacks.
We check if we have a melon inside the array — if we do, we chew the melon, after chewing we throw away the melon. We’re also handling exceptions with the
err callback is the first argument always in the Node world — best practices!
Just to throw you off a little — I made the previous code as readable as I can, here’s how it might look more often:
You can imagine, couple more callbacks and we’re on the highway to [callback] hell — pun intended!
Promises to the rescue!
Promises are a clean way to write asynchronous code. The promise has a single argument, which is a callback.
The callback has two arguments, the
And if we use the arrow function to shorten the code:
Inside the promise block, we can decide when to resolve and when to reject the promise.
Inside the promise we check if we have a melon. If we do, let’s
resolve the function with the value we pass inside
resolve — we can pass literally any value to the
Promises are immediately invoked/resolved, thus why we see the
console.log without calling the promise.
Promises are called and chained with the
catch methods. Think of it like this: the promise has resolved with a value — what do we do with it?
This is where the
catch syntax comes in. They are both callbacks which accept one argument, which is the return value passed inside the promise.
Here’s how we could handle a promise rejection:
Right, now our promise is not very dynamic — why?
Well, because we have an if statement that isn’t dynamic. Promises are extremely powerful when wrapped inside a function. We call them higher order functions.
Do you notice the small change? We wrapped our promise inside a function which takes one argument in this case. This gives our promises huge flexibility. We can pass any condition to our promise and based on that condition, it will get either rejected or resolved.
Here’s the fully working promise which gets resolved.
And the rejected promise.
Starts to look familiar? You might have seen Axios API calls like the one below.
Axios + React API call example (promise based)
Or the fetch API call;
Fetch + react API call example (promise based)
What do they have in common?
Well, for starters they’re both a promise. They’re fundamentally using promises under the “hood”. Just like we wrapped our promise inside a function, so do both of these examples.
Secondly, they’re both asynchronous code. Promises are naturally asynchronous.
If you find promises confusing — please read this article and come back ❤
Here’s how an asynchronous API call looks like:
It’s safe to say promises are much better than callbacks. Promises have their own flaws although — promises can get out of hand quite quickly.
What if there’s a better way, an even cleaner way. Async/wait to the rescue!
We mark the function as
async — inside the function we mark the asynchronous code with
Notice how we don’t call the promise constructor anymore and how there are much less
What about error handling?
Our current async/await doesn’t handle exceptions. This can lead to catastrophic bugs which might crash your app.
Try…catch to the rescue!
The try catch block attempts to execute the code and if it runs into any exceptions/problems, it passes the error object to the catch block and executes the code inside the catch block.
Here’s how our async/await fetch would look with error handling.
This is just one of many examples, there are many ways to leverage async/wait. If you’re curious — here’s a pretty good example StackOverflow answer exploring the alternatives.
Bonus: Check out this great article on misconceptions about async/await.
Thanks for reading and I hope you found this useful!
I’d love to connect with you directly on Twitter and pass on more knowledge in the future. ❤
More cool articles here;
About the author:
Here are some of my previous articles:
Here are some of the best resources to improve your coding skills
There are lots of high-quality coding tutorials, books, and overall resources on the web. I’ve gathered the very best…medium.comHow to set-up a powerful API with Nodejs, GraphQL, MongoDB, Hapi, and Swagger
Due to high demand I’m extending the list of fun apps to build. 😁medium.freecodecamp.org