Output Quiz #13 — Mixed Async Topics (Easy)

10 entry-level output questions sampling one foundational concept from each area — scope, closures, event loop, this, coercion, promises, chaining, combinators, async/await, and setTimeout interleaving.

10 min read
JavaScript
Interview
Output

TABLE OF CONTENTS
Output Quiz #13 — Mixed Async Topics (Easy)

Ten entry-level output questions sampling one fundamental concept from each major area — scope, closures, event loop, this, coercion, promises, chaining, combinators, async/await, and setTimeout interleaving. If you can answer all ten cold, your JS async fundamentals are interview-ready.


Q1 — var hoisting

Loading editor...

Show answer

Output:

undefined
5

Why: var x is hoisted to the top of its scope and initialized to undefined. So the first console.log(x) sees undefined — not a ReferenceError (which is what let/const would give). The assignment x = 5 runs inline, so the second log sees 5.


Q2 — Classic var loop + setTimeout

Loading editor...

Show answer

Output:

3
3
3

Why: var i is function-scoped — there is only one i. By the time the setTimeout callbacks run (macrotasks), the loop has finished and i is 3. All three callbacks close over the same i variable and log its current value: 3. Change var to let and you get 0, 1, 2.


Q3 — setTimeout(0) vs Promise.then

Loading editor...

Show answer

Output:

A
D
C
B

Why: Sync code first: "A", "D". Then microtask queue is drained: "C" (.then() callback). Then the macrotask queue runs: "B" (setTimeout callback). Key rule: synchronous → microtasks → macrotasks. Promise .then() always beats setTimeout(0).


Q4 — this binding — method extracted and called standalone

Loading editor...

Show answer

Output:

undefined

Why: fn is called as a standalone function, not as a method of obj. In non-strict mode, this would be the global object (and this.name would be undefined unless there's a global name). In strict mode / ES modules, this is undefined and this.name throws TypeError. The key rule: this is determined by the call-site, not the original object.


Q5 — Type coercion with +

Loading editor...

Show answer

Output:

12
2
105

Why: + with a string operand triggers string concatenation: 1 + "2""12". - always coerces to numbers: "3" - 12. Chained + is left-to-right: 5 + 510, then 10 + "5""105".


Q6 — Promise executor is synchronous

Loading editor...

Show answer

Output:

start
executor
end

Why: The Promise executor function runs synchronously at construction time. "executor" logs between "start" and "end". The resolved value "done" goes nowhere because there is no .then() — but the executor body itself is synchronous.


Q7 — .catch() recovery

Loading editor...

Show answer

Output:

caught: error
then: recovered

Why: .catch() that returns a plain value converts the chain back to the resolved track. The .then() after .catch() runs normally and receives "recovered". This is the recovery pattern — handle the error, return a fallback, and the chain continues.


Q8 — Promise.all preserves input order

Loading editor...

Show answer

Output:

["first", "second", "third"]

Why: Promise.all returns values in input order, not resolution order. Even if the third Promise resolved first, the output array mirrors the input array. This matters when Promises have different resolve times — the array position is always preserved.


Q9 — return vs return await in try/catch

Loading editor...

Show answer

Output:

caught with await: fail

Why: return Promise.reject("fail") exits the try block immediately — the catch never runs. return await Promise.reject("fail") stays inside the try, the await unwraps the rejection into a throw, and the catch intercepts it. withoutAwait() returns a rejected Promise that the caller must handle; withAwait() recovers inside the function.


Q10 — Promise inside setTimeout

Loading editor...

Show answer

Output:

P
T
P inside T

Why: Microtask "P" runs first (after sync). Then the macrotask fires: "T", then queues "P inside T" as a microtask. After that macrotask exits, microtasks drain again: "P inside T". The golden rule: after every macrotask, all microtasks are drained before the next macrotask — including microtasks created by the macrotask itself.


Key Rules

TopicRule
Scopevar is hoisted to undefined; let/const hit TDZ
ClosuresClose over variables, not values; var in loop → all share the same binding
Event LoopSync → microtasks (Promise, queueMicrotask) → macrotasks (setTimeout)
thisDetermined by call-site; extracted method loses its object binding
Coercion+ with string → concatenation; -/*// → numeric coercion
PromisesExecutor sync; .then() / .catch() are microtasks
.catch()Returning a value converts chain back to resolved
Promise.allValues in input order; fail-fast on first rejection
async/awaitreturn exits try; return await stays and lets catch intercept
setTimeout + PromiseMicrotask from macrotask runs before next macrotask

Go Deeper


Let's Connect

© 2026 Naveen Karthik // Built with React & MUI