

Be Careful with Async Functions that Return Booleans
source link: https://www.aleksandrhovhannisyan.com/blog/dev/async-functions-that-return-booleans/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Be Careful with Async Functions that Return Booleans
Here’s a fun bug I recently encountered… Let’s say we have this async
JavaScript function:
const isBroken = async () => {
return false;
}
if (isBroken()) {
throw new Error("Oopsie woopsie");
}
I’ve kept the code simple for this post; in reality, you’ll probably fetch data asynchronously in the function (otherwise, there’s no need to mark it as async
):
const isBroken = async () => {
const x = await y();
// ...
// ... more stuff here maybe
// ...
return x === 42;
}
if (isBroken()) {
throw new Error("Oopsie woopsie");
}
Either way, does the body of the if
statement execute? Take a second to think this through. You can check if you’re right by copying the first code sample and executing it in your dev tools.
(You can probably already guess the answer, though, just based on the fact that I’m writing this post.)
Async Functions, Booleans, and Truthiness: A Slippery Bug
The if
statement in this code will always execute its body, regardless of what the async function returns. ESLint won’t flag this as an error. TypeScript technically should, but it has not yet implemented this warning for un-awaited async functions.
To understand why the expression always evaluates to true
, recall that async/await
is just syntactic sugar for Promises. In JavaScript, an async
function actually wraps its return value in a Promise
object—even if it seems like the function is directly returning a value, and even if the function does not await
anything.
We can verify this by logging the function call:
> console.log(isBroken())
Promise {<fulfilled>: false}
Our async function’s return value is not false
itself but rather a Promise object that resolved with the value false
. In other words, it’s the same as doing this:
const isBroken = () => {
return Promise.resolve(false);
}
if (isBroken()) {
throw new Error("Oopsie woopsie");
}
Spot the problem? This is an issue of truthiness: a Promise
object is not one of the eight falsy values in JavaScript, so checking its truthiness is pointless: When coerced to a boolean, a Promise is always true
.
For the code above to work as intended, you’ll need to await
the result in another async
function (or, equivalently, chain a .then
call on the returned Promise object):
const isBroken = async () => {
return false;
}
const foo = async () => {
const somethingIsWrong = await isBroken();
if (somethingIsWrong) {
throw new Error("Oopsie woopsie");
}
}
This is a pretty interesting bug that you may run into, though some basic tests will probably catch it before you need to go looking for it yourself. However, in the absence of tests, unless you remember that the function is async (and that async functions return Promises), this bug could easily slip right past you.
Recommend
-
75
Store a associative array of booleans in the database efficiently using binary numbers.
-
50
I’ll start this article with a warning, I mention the use of Lambda Calculus, but do not let that scare you! I promise, no knowledge of λ-Calculus is required to understand or use the main concepts in this article! Phew!
-
57
In my last Functional JS article, we went over recursive patterns that allow you to operate/iterate over array values. This time, we’re going to get a bit more abstract to hopefully explain some of…
-
11
Programming with truth and statefulness. I like formal specification because I don’t really understand it. That is kind of my...
-
9
Compiling a Lisp: Booleans, characters, nil September 2, 2020 first –
-
4
Writing a Lisp, Part 1: Booleans October 28, 2016 Last time we wrote a simple interpreter that could read in numbers. That’s cool and all, but we’ll need to re...
-
8
Basic Data Types in Python 3: BooleansWelcome back to our ongoing series of blog posts on basic data types in Python 3! Last time, we explored the functionality of
-
8
« back — written by Brent on February 14, 2020 Bitwise booleans in PHP ...
-
7
Python Booleans: Leveraging the Values of Truth Understanding how Python Boolean values behave is important to programming well in Python. The Python Boolean type is one of Python’s
-
12
Three ways to print booleans as 'True' or 'False' in C++Skip to main content Three ways to print booleans as 'True' or '...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK