Promise handling may have gotten us out of the nine circles of callback hell, but unfortunately we have yet another circle to circumvent and that circle involves all the frustrations that come with promise chainings. Luckily for us, the same JavaScript gods that helped Dante out of the inferno have also bestowed upon us the blessed ways of Async/Await. Okay, so I’ve never read Dante’s Inferno, but I have gotten my hands dirty with Async/Await during a time when my many then/catch blocks became quite bloated and inflexible to work with. Before getting into that adventure, allow me to give you a futile history of Async/Await.
Asynchronous workflows were first introduced to the F# programming language in 2007 with await points, which then influenced the Async/Await mechanism in the C# language. Eventually Haskell’s lead developer Simon Marlow created a bombshell of an async package in 2012 leading to its adoption in other languages such as Python, Rust, C++, etc. JavaScript was a little late to the game but eventually integrated Async/Await in ECMAScript 2017 edition, and the rest is history.
Async/Await are essentially syntactical sugar wrapped around making promises easier to work with and are first declared with the (you guessed it) Async keyword. Before we get into how they work, let us first look at our good old friends, then/catch.
const salutation = new Promise((resolve, reject) => {
resolve("What is up my fellow homie?");
});
salutation
.then((value) => {
console.log("The first promise was resolved", value);
})
.then((value) => {
console.log("The second promise was resolved", value);
})
.catch((error) => {
console.error("Error: The promise is rejected.", error);
})
.finally(() => {
console.log(
"This promise is now settled, meaning it has been resolved or rejected."
);
});
It is perhaps true for many developers that then/catch blocks are easier to interpret than their async/await constituents, much like how if/then conditionals are simpler to intuit than switch/case statements, but it is important not to use simplicity as a crutch in coding and to always venture into a new terrain. In this example, we have a variable salutation that returns a promise, which is then attached with then/catch blocks that return useless code that I have written on the fly.
Here is an example of an async/await promise handling that does the same thing:
async function doSomething() {
const value = await greeting;
}
async function doSomething() {
try {
const value = await greeting;
console.log("The first promise was resolved", value);
} catch((error) {
console.log("The second promise was resolved", value);
} finally {
console.log(
"This promise is now settled, meaning it has been resolved or rejected");
}
}
Notice how this code is a little bit shorter. The keyword async basically makes sure that the doSomething function returns a promise, while also wrapping non-promises within in it. The await keyword ensures that JavaScript will suspend any progress within this function until the promise is settled and returned. And as usual, in the case of a rejection, the error is thrown.
Now that you have at least heard of the existence of Async/Await, please don't AWAIT to get out of your comfort zones and implement them in your own codes. There is no need to try to catch hell (a pun on try-catch hell), I promise.
Top comments (0)