Async & Await, a pair of words you might have heard of earlier in your JavaScript career, or maybe your teacher told you to utilize Async/Await to make your function a non-blocking function and you have literally no clue what this is about!? Well then let's dive into the first chapter of this article. We'll first focus on the aspect of having an async
functions and then going deeper into the usage of await as it is more a syntactic sugar
for us developers.
Async
Async, also called asynchronous, is a common technique to make your code non-blocking. But what does that mean? Let's explain it with a basic NodeJS example:
const fs = require('fs')
// 1. Example, the common sync'd code execute
// logic: everything will stop here until it has finally loaded the file (imagine a file of 2GB)
const myFilesContent = fs.readFileSync('./path/to/file')
// 2. Example Async (callback based)
// logic: Start loading the file, and "call" me back later when you are done
fs.readFile('./path/to/file', (error, buffer) => {
// ah we got that file read into our memory and it's read for usage
});
// 2. Example Async (promised based)
// logic: Start loading the file and after finishing loading, then please execute the code
new Promise((resolve, reject) => fs.readFile('./path/to/file', (error, buffer) => {
// function without a return either reject if error are happening
// or resolve the to resolving object
// The promise will wait until either of those two function has been called!
if(err){
reject(err)
}
resolve(buffer)
})).then((fileBuffer) => {
// thank you for providing me with your buffer.
}).catch(error => {
// ahh, snap something wrong happened!
})
Okay, that looks quite simple - but:
- Where's the async part over here?
- Are there no indicators in Javascript for working with an asynchronous function?
Basically, yes there are, but they are rarely used as they were added within the latest standardization cycle. That is the reason why most of the projects you'll come or came across will probably either apply callback based
or promised based
executions for asynchronous operations.
Eventually, it's up to you to remember async structures like these, when you come across callbacks and/or promises.
Let us also look into the syntactic sugar
- world, where we can use the keyword async
to signal a function to act as an asynchronous function. And we will also look deeper into on what it actually does in the background. (Fun-Fact: async functions
will just wrap your output into a new promise)
// async function way of doing asynchronous fetching
const fetchNewsletter = async options => {
// fetch your newsletter and await its arrival
// Caution: fetch is already a function which returns a promise
const response = await fetch(
'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty',
options
);
// check if the response is ok, like the normal way you would do it
if (!response.ok) {
throw new Error('Ups.');
}
// Caution: .json() returns a new Promised value!
// the returned value can be everything and will be wrapped into a new promise
return await response.json();
};
// the above shown function will look something like this:
const fetchNewsletterPromised = options =>
fetch(
'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty',
options
).then(response => {
if (!response.ok) {
throw new Error('Ups.');
}
return response.json();
});
// syntactic sugar function
fetchNewsletter()
.then(newsletter => {
// have fun reading it later ;)
})
.then(error => {
// ahhh snap!
});
// non syntactic sugar function
fetchNewsletterPromised()
.then(newsletter => {
// have fun reading it later ;)
})
.then(error => {
// ahhh snap!
});
As a remark there, the initial code for the async function seems to be a bit longer than the promised one, but in my opinion it isn't a problem as it is comfortable to read and more transparent then having a chain of then
's which can become really really disturbing and build more overhead, if you have more than one chain to resolve there.
And what does the await
syntax within the first function do? This unpacks the Promised value of the fetch function we called there. A self-explanatory example right here:
const XMASParty = async promisedPresent => {
const myRealPresent = await promisedPresent;
const mood = await myRealPresent.isWishedOne
? enjoyPresent(myRealPresent)
: enjoyItNeverTheLess(myRealPresent);
return mood;
};
Never the less, I really support the trend we have here and I believe we are correcting most of the core concepts of JavaScript in a very great way. Although for newcomers it might be unusual to have nearly 3 patterns of arranging async code in JavaScript. Furthermore, they also cause a lot of pitfalls within the language as you have to understand promises in depth before heading into Async/Await stuff.
Top comments (2)
I hate promises in JS
I know that frustration, but at some point also you will become a friend with it as the learning curve for promises is quite hard. Or just use Async 😬