D
Dart LanguageIntermediate30 XP7 min read

Explain Dart's async/await, Future, and the microtask queue

TL;DR: Dart is single-threaded with an event loop. async/await syntactic sugar wraps code in Future continuations. Microtasks (scheduleMicrotask, Future.value) run before the next event; regular async operations (I/O, timers) are events.

Full Answer

Dart Event Loop

Dart runs on a single thread with two queues: the event queue (I/O, timers, user events) and the microtask queue. The event loop always drains the microtask queue completely before taking the next event.

Microtask vs Event queue

  • Microtask queue: Future.value(), Future.sync(), scheduleMicrotask() — run before next event
  • Event queue: I/O callbacks, Timer, network responses — run as events
  • await on a completed Future schedules the continuation as a microtask
  • await on a pending Future (e.g., HTTP request) schedules continuation as an event when it completes
🎯

This is why long synchronous loops block the UI in Flutter — they don't yield to the event loop. Use compute() or Isolates for CPU-intensive work.

Code Examples

dartExecution order: microtasks vs events
Output
1 — sync start
2 — sync end
2.5 — explicit microtask
3 — microtask
4 — event (Timer-like)

Interview Tip

💡

Key insight: await suspension points are microtasks when the Future is already complete. This is why multiple awaits in a row can still block the UI if they all complete synchronously — use Future.delayed(Duration.zero) to yield to the event loop.

#async#await#future#microtask#event-loop