Question #151EasyAsync Programming

What is the use of future.microtask with perfect example to understand the use case of it?

#future

Answer

Overview

text
Future.microtask()
schedules a function to run as a microtask — after the current synchronous code finishes but before any other
text
Future
callbacks or timers. It runs at the very next opportunity in the Dart event loop.


The Dart Event Loop

text
Synchronous code → Microtask queue → Event queue (Futures, timers, I/O)
  • Synchronous code runs first
  • Microtask queue (Future.microtask, scheduleMicrotask) runs next — before any events
  • Event queue (Future, Timer, I/O callbacks) runs last

Basic Example

dart
void main() {
  print('1 - Sync start');

  Future(() => print('4 - Future (event queue)'));

  Future.microtask(() => print('3 - Microtask'));

  print('2 - Sync end');
}

// Output:
// 1 - Sync start
// 2 - Sync end
// 3 - Microtask       ← runs before the regular Future
// 4 - Future (event queue)

Practical Use Case 1: Defer work to after build

dart

void initState() {
  super.initState();

  // ❌ Cannot call setState during initState synchronously
  // setState(() { ... }); // Throws error

  // ✅ Use microtask to run after initState completes
  Future.microtask(() {
    setState(() {
      _data = 'Loaded';
    });
  });
}

Practical Use Case 2: Priority async work

dart
void processPayment() {
  // Schedule critical validation as microtask (highest priority)
  Future.microtask(() => validateCard());

  // Schedule non-critical log (lower priority)
  Future(() => logPaymentAttempt());

  print('Payment initiated');
}

// Output order:
// Payment initiated
// validateCard()     ← microtask first
// logPaymentAttempt() ← regular Future after

Practical Use Case 3: Avoid setState during build

dart

Widget build(BuildContext context) {
  // ❌ Never call setState directly in build
  
  // ✅ Defer it to after the current build frame
  Future.microtask(() {
    if (mounted) setState(() => _count++);
  });

  return Text('$_count');
}

Future.microtask vs scheduleMicrotask

dart
// These are equivalent
Future.microtask(() => doWork());
scheduleMicrotask(() => doWork());

Execution Order Summary

dart
void main() {
  print('A');                               // 1st
  Timer(Duration.zero, () => print('E'));   // 5th (timer = event queue)
  Future(() => print('D'));                 // 4th (Future = event queue)
  Future.microtask(() => print('C'));       // 3rd (microtask)
  scheduleMicrotask(() => print('B+'));     // also microtask
  print('B');                               // 2nd
}
// Output: A → B → B+ → C → D → E

When to Use Future.microtask

ScenarioUse
Post-initState work that needs setState✅ Future.microtask
Running something after current frame✅ Future.microtask
Priority async work before other Futures✅ Future.microtask
Delaying by time❌ Use
text
Future.delayed
instead
Heavy computation❌ Use
text
Isolate
or
text
compute

Key Rule:

text
Future.microtask
runs after current sync code but before any queued events. It is ideal for deferring work that must happen before the next event loop cycle but after the current execution context completes.