Leaderboard
Javascript Jul 20, 2026
Javascript Async Await Destructuring Clean Pattern

JavaScript Async/Await — What does this output?

This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Async Await Destructuring Clean Pattern and improve your technical interview readiness.

async function fetchUser() {
  return { name: "Alice" }
}
async function main() {
  const user = await fetchUser()
  const { name } = user
  console.log(`User: ${name}`)
}
main()
A undefined
B "User: Alice"
C Promise object
D TypeError

Detailed Explanation

Why This Question Matters

If you've spent any time in a JavaScript codebase over the last few years, you've seen async and await everywhere. On the surface, they make asynchronous code look synchronous, which is great for readability. But there's a mental trap here: developers often forget that async functions *always* return a promise, regardless of what you actually return inside the body.

This specific challenge tests whether you actually understand the "Promise wrap" that happens under the hood. If you mistake a Promise for the actual value it resolves to, your code will crash—or worse, you'll spend three hours debugging why your variable says [object Promise] instead of the data you expected.

Understanding the Code

Let's look at the snippet again:

async function fetchUser() {
  return { name: "Alice" }
}

async function main() {
const user = await fetchUser()
const { name } = user
console.log(User: ${name})
}

main()

At first glance, it looks trivial. But let's trace the execution.

First, we have fetchUser. It's marked as async. In JavaScript, when you mark a function as async, the engine automatically wraps the return value in a Promise. Even though we are returning a plain object { name: "Alice" }, the function actually returns a Promise that resolves to that object.

Then we have main. Inside main, we call await fetchUser().

The await keyword is the magic part. It tells the JavaScript engine: "Pause the execution of this function until the promise returned by fetchUser resolves. Once it resolves, give me the actual value inside that promise."

Because we used await, the variable user doesn't hold a Promise; it holds the actual object { name: "Alice" }. From there, we use object destructuring (const { name } = user) to grab the string "Alice" and log it.

Finding the Correct Answer

The correct answer is Option B: User: Alice.

Here is why the other common guesses are wrong:

"It outputs [object Promise]"
This happens if you forget the await. If the code was const user = fetchUser(), then user would be the Promise itself. Destructuring { name } from a Promise object would result in undefined because Promises don't have a name property.

"It throws a Syntax Error"
Some might think you can't use await inside main or that the destructuring is invalid. But since main is also marked as async, await is perfectly legal.

"It outputs nothing/undefined"
This usually happens if someone thinks fetchUser needs to be called with a .then() block. While you *could* use .then(), await is just syntactic sugar for the same process.

Common Mistakes Developers Make

The most frequent mistake I see—especially with mid-level devs—is "forgetting the await chain."

Imagine if fetchUser called another function, like db.query(). If you forget to await the internal call, you might return a Promise that resolves to another Promise. JavaScript handles "nested" promises reasonably well (it flattens them), but it creates a lot of confusion when you start mixing async/await with old-school .then() callbacks.

Another trap is the "Async Infection." Once a function is async, every function that calls it and needs its value must also be async (or handle the promise manually). This ripples up through your call stack. If you forget to await at the top level, your logic might execute out of order, leading to those classic "race condition" bugs where your UI tries to render data that hasn't actually arrived yet.

Real-World Usage

In a production environment, you aren't just returning hardcoded objects. You're hitting APIs, querying MongoDB, or reading files from a disk.

async function getUserProfile(userId) {
  const response = await fetch(/api/users/${userId});
  const data = await response.json(); // .json() also returns a promise!
  return data;
}

Notice how await is used twice here. The first is for the network request, and the second is for parsing the body. If you miss either one, your app breaks.

In large-scale engineering, we often use Promise.all() to run these async tasks in parallel. If you have five fetchUser calls, awaiting them one by one is a performance killer. You'd instead wrap them in Promise.all([fetchUser(1), fetchUser(2)...]) to fire them off simultaneously.

Key Takeaways

- Async always returns a Promise. Even if you return a string, a number, or null, it's wrapped in a Promise.
- await unwraps the Promise. It pauses the local function execution and extracts the resolved value.
- Destructuring works on the resolved value. You can't destructure a Promise; you can only destructure the value *after* it has been awaited.
- Check your call stack. If you're seeing [object Promise] in your logs, you probably missed an await somewhere upstream.

Why this matters

Understanding Async Await Destructuring Clean Pattern is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.

📝
Reviewed by CodeShot Editorial
Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

Ready for your shot?

Join thousands of developers solving one logic puzzle every morning.

Solve Today's Challenge →