JavaScript Event Loop & Microtasks Introduction Quiz

JavaScript
0 Passed
0% acceptance

Answer 50 questions about the JavaScript event loop, call stack, macrotasks, microtasks, promise timing, rendering, async APIs, starvation risks, and debugging workflows.

50 Questions
~100 minutes
1

Question 1

What does the call stack track in JavaScript engines?

A
The chain of currently executing function frames
B
All promises that have been created
C
Pending DOM mutations
D
The GPU command queue
2

Question 2

Why must the call stack be empty before the event loop pulls the next macrotask?

A
Because JavaScript is single-threaded and cannot start a new task until current execution finishes
B
Because macrotasks run in parallel with the stack
C
Because the stack stores DOM nodes that must be cleared
D
Because promises need the stack to be full
3

Question 3

What prints?

javascript
function second() {
  console.log('second')
}
function first() {
  console.log('first')
  second()
}
first()
A
first then second
B
second then first
C
Only first
D
Only second
4

Question 4

What happens if a function recursively calls itself without a base case?

A
The call stack overflows because frames accumulate indefinitely
B
The event loop automatically fixes the recursion
C
The GPU handles the recursion
D
The browser silently converts it into a promise chain
5

Question 5

What prints?

javascript
console.log('A')
setTimeout(() => console.log('B'), 0)
console.log('C')
A
A, C, B
B
A, B, C
C
B, A, C
D
C, B, A
6

Question 6

What is the main job of the event loop?

A
Coordinate execution between the call stack, task queues, and rendering phases
B
Control CSS layout rules
C
Manage GPU shaders
D
Compile TypeScript at runtime
7

Question 7

Why is the event loop crucial for non-blocking behavior?

A
It lets long-running operations schedule callbacks without freezing the main thread
B
It spawns multiple JS threads by default
C
It moves synchronous code to workers automatically
D
It disables garbage collection
8

Question 8

Which statement describes a typical loop tick?

A
Process one macrotask, then drain the microtask queue, then possibly render
B
Process all macrotasks before microtasks
C
Render first, then look at queues
D
Skip microtasks when promises resolve
9

Question 9

What prints?

javascript
console.log('loop start')
queueMicrotask(() => console.log('microtask'))
console.log('loop end')
A
loop start, loop end, microtask
B
loop start, microtask, loop end
C
microtask, loop start, loop end
D
loop end, loop start, microtask
10

Question 10

Why do browsers sometimes defer rendering until after microtasks run?

A
To ensure the DOM state is stable before painting
B
To improve CSS specificity
C
To prioritize GPU commands
D
To recompile JavaScript
11

Question 11

Which of these schedules a macrotask?

A
setTimeout
B
Promise.resolve().then
C
queueMicrotask
D
MutationObserver
12

Question 12

What prints?

javascript
console.log('start')
setTimeout(() => console.log('timer'), 0)
Promise.resolve().then(() => console.log('promise'))
console.log('finish')
A
start, finish, promise, timer
B
start, promise, finish, timer
C
start, timer, promise, finish
D
promise, timer, start, finish
13

Question 13

Why are macrotasks sometimes called tasks?

A
Specifications refer to them simply as tasks, encompassing timers, message events, and user input callbacks
B
Because they represent microtasks
C
Because they only run in Node.js
D
Because they are smaller than microtasks
14

Question 14

What prints?

javascript
setTimeout(() => console.log('T1'), 0)
setTimeout(() => console.log('T2'), 0)
console.log('sync')
A
sync, T1, T2
B
T1, T2, sync
C
sync, T2, T1
D
T2, T1, sync
15

Question 15

Why might you split heavy work across multiple macrotasks?

A
To yield back to the browser between chunks, keeping the UI responsive
B
To disable garbage collection
C
To ensure the work runs on the GPU
D
To avoid promise usage
16

Question 16

Which API adds a callback to the microtask queue?

A
Promise.then
B
setInterval
C
requestAnimationFrame
D
setTimeout
17

Question 17

What prints?

javascript
Promise.resolve().then(() => console.log('microtask 1'))
Promise.resolve().then(() => console.log('microtask 2'))
console.log('sync')
A
sync, microtask 1, microtask 2
B
microtask 1, microtask 2, sync
C
sync, microtask 2, microtask 1
D
microtask 2, sync, microtask 1
18

Question 18

Why must engines fully drain the microtask queue before rendering?

A
Because microtasks can mutate DOM state that would invalidate a paint
B
Because CSS animations depend on microtasks
C
Because microtasks allocate GPU memory
D
Because microtasks recompile scripts
19

Question 19

What prints?

javascript
queueMicrotask(() => {
  console.log('A')
  queueMicrotask(() => console.log('B'))
})
console.log('sync')
A
sync, A, B
B
A, B, sync
C
sync, B, A
D
A, sync, B
20

Question 20

How do MutationObserver callbacks behave?

A
They are delivered as microtasks after DOM mutations
B
They run as macrotasks
C
They run synchronously during the mutation
D
They require requestIdleCallback
21

Question 21

When does a promise reaction callback run?

A
On the microtask queue after the current synchronous work completes
B
Immediately upon resolve() even if synchronous code is running
C
Only after all timers finish
D
Only if await is used
22

Question 22

What prints?

javascript
const p = Promise.resolve('done')
p.then(value => console.log(value))
console.log('after')
A
after, done
B
done, after
C
after only
D
Throws ReferenceError
23

Question 23

What prints?

javascript
Promise.resolve().then(() => console.log('first then'))
Promise.resolve().then(() => console.log('second then'))
console.log('sync work')
A
sync work, first then, second then
B
first then, second then, sync work
C
sync work, second then, first then
D
second then, first then, sync work
24

Question 24

Why should you avoid long microtask chains that never yield?

A
They can prevent rendering or new macrotasks from running, freezing the UI
B
They speed up garbage collection excessively
C
They disable async/await
D
They block CSS parsing
25

Question 25

How does async/await relate to promise timing?

A
await pauses the function and resumes it in a microtask once the awaited promise settles
B
await makes promises synchronous
C
await converts promises into macrotasks
D
await forces timers to resolve first
26

Question 26

Which typically runs first: a 0ms setTimeout or Promise.resolve().then?

A
Promise.resolve().then, because microtasks run before the next macrotask
B
setTimeout, because timers preempt microtasks
C
They run simultaneously
D
Whichever was created last
27

Question 27

What prints?

javascript
setTimeout(() => console.log('timeout'), 0)
Promise.resolve().then(() => console.log('promise'))
console.log('sync')
A
sync, promise, timeout
B
sync, timeout, promise
C
promise, sync, timeout
D
timeout, promise, sync
28

Question 28

What prints?

javascript
Promise.resolve().then(() => console.log(1))
setTimeout(() => console.log(2), 0)
Promise.resolve().then(() => console.log(3))
A
1, 3, 2
B
2, 1, 3
C
1, 2, 3
D
3, 1, 2
29

Question 29

Why is setImmediate in Node.js considered a macrotask?

A
It schedules callbacks on the check phase, similar to other macrotasks
B
It is identical to process.nextTick
C
It is synchronous
D
It preempts microtasks
30

Question 30

How can you ensure a timer runs after the current microtasks but before rendering?

A
You cannot; macrotasks always wait until microtasks finish, and rendering may run afterward
B
Use requestAnimationFrame to force earlier execution
C
Use await to make the timer synchronous
D
Use queueMicrotask to schedule the timer
31

Question 31

When do browsers typically run requestAnimationFrame callbacks?

A
Right before the next paint, after microtasks are drained
B
Immediately when called
C
During the microtask queue
D
Only when the page is hidden
32

Question 32

Why might layout thrashing occur?

A
Rapid synchronous reads and writes to DOM layout triggers repeated recalculations before rendering
B
Promises resolved too quickly
C
Timers set to 0ms
D
Use of CSS variables
33

Question 33

What prints?

javascript
requestAnimationFrame(() => console.log('paint' ))
console.log('sync work')
A
sync work, paint
B
paint, sync work
C
paint only
D
sync work only
34

Question 34

How can microtasks delay rendering indefinitely?

A
If microtasks continuously schedule new microtasks, the browser never reaches the render phase
B
By flushing macrotasks first
C
By increasing CSS priorities
D
By forcing GPU context loss
35

Question 35

Why is yielding via requestIdleCallback useful?

A
It lets the browser run work only when it has spare time, avoiding jank during critical rendering periods
B
It converts microtasks into macrotasks
C
It guarantees execution every frame
D
It forces work onto workers
36

Question 36

How do fetch() responses enter the event loop?

A
Network completion triggers a macrotask that ultimately resolves the associated promise
B
fetch places handlers on the microtask queue immediately
C
fetch blocks the call stack until the response arrives
D
fetch executes entirely inside a worker thread
37

Question 37

What prints?

javascript
async function run() {
  console.log('before fetch')
  await Promise.resolve()
  console.log('after await')
}
run()
console.log('global')
A
before fetch, global, after await
B
before fetch, after await, global
C
global, before fetch, after await
D
after await, before fetch, global
38

Question 38

Why does setInterval use the macrotask queue?

A
Each tick is delivered as a separate task to avoid reentrancy while previous work is still running
B
Intervals are microtasks by design
C
Intervals run synchronously
D
Intervals create workers
39

Question 39

How do Web Workers interact with the event loop?

A
Each worker has its own event loop; messages between main thread and workers are scheduled via tasks
B
Workers share the same stack as the main thread
C
Workers execute only microtasks
D
Workers run without any event loop
40

Question 40

Why should long-running synchronous work be moved to a worker when possible?

A
It prevents blocking the main thread’s event loop, keeping UI interactions responsive
B
It automatically converts code to microtasks
C
It doubles the CPU clock speed
D
It disables garbage collection
41

Question 41

What is microtask starvation?

A
A state where microtasks continually reschedule themselves, preventing macrotasks or rendering from running
B
A shortage of timers
C
A GPU memory leak
D
A CSS specificity bug
42

Question 42

What prints?

javascript
let count = 0
function spin() {
  if (count < 3) {
    count += 1
    queueMicrotask(spin)
  }
}
queueMicrotask(spin)
console.log('done scheduling')
A
done scheduling, then the loop completes silently
B
spin runs before done scheduling
C
done scheduling never logs
D
Throws ReferenceError
43

Question 43

How can you avoid microtask starvation when chaining promise reactions?

A
Occasionally yield via setTimeout or await a resolved timer to let the event loop progress
B
Convert promises into synchronous code
C
Disable queueMicrotask globally
D
Rely on CSS animations
44

Question 44

Why might microtask starvation be hard to detect?

A
The UI simply freezes without clear errors, because microtasks run legitimately but never yield
B
Browsers throw syntax errors for starvation
C
The GPU logs warnings
D
CSS selectors fail to apply
45

Question 45

Which technique helps limit microtask loops?

A
Track iterations and break the loop or schedule a macrotask once a threshold is reached
B
Use only synchronous recursion
C
Disable promises in the project
D
Increase CSS z-index
46

Question 46

How can the Performance panel help debug event loop stalls?

A
It shows flame charts revealing long tasks, microtask activity, and rendering gaps
B
It automatically fixes code
C
It disables garbage collection
D
It forces the browser into slow motion
47

Question 47

Why is logging timestamps useful when tracking async order?

A
Timestamps reveal when callbacks actually fire relative to each other, clarifying queue order
B
They convert macrotasks into microtasks
C
They disable timers
D
They force synchronous fetch
48

Question 48

What prints?

javascript
console.log('trace 1')
setTimeout(() => console.log('trace 2'))
Promise.resolve().then(() => console.log('trace 3'))
console.log('trace 4')
A
trace 1, trace 4, trace 3, trace 2
B
trace 1, trace 3, trace 4, trace 2
C
trace 1, trace 2, trace 3, trace 4
D
trace 3, trace 1, trace 2, trace 4
49

Question 49

What DevTools feature helps inspect microtask queues?

A
Async stack traces show the call path across microtask boundaries
B
The color picker
C
The device toolbar
D
The sources prettify button
50

Question 50

Why should you annotate tricky asynchronous flows with inline comments?

A
Documenting expected ordering clarifies intent for future maintainers and aids debugging
B
Comments change the event loop ordering automatically
C
Comments disable lint rules
D
Comments convert microtasks into macrotasks

QUIZZES IN JavaScript