scheduleMicrotask function

void scheduleMicrotask(
  1. void callback()
)

Runs a function asynchronously.

Callbacks registered through this function are always executed in order and are guaranteed to run before other asynchronous events (like Timer events, or DOM events).

Warning: it is possible to starve the DOM by registering asynchronous callbacks through this method. For example the following program runs the callbacks without ever giving the Timer callback a chance to execute:

main() {
  Timer.run(() { print("executed"); });  // Will never be executed.
  foo() {
    scheduleMicrotask(foo);  // Schedules [foo] in front of other events.
  }
  foo();
}

Other resources

  • The Event Loop and Dart: Learn how Dart handles the event queue and microtask queue, so you can write better asynchronous code with fewer surprises.

Implementation

@pragma('vm:entry-point', 'call')
void scheduleMicrotask(void Function() callback) {
  Zone currentZone = Zone._current;
  if (identical(_rootZone, currentZone)) {
    // We know register has no effect, run just calls the function,
    // and `_rootScheduleMicrotask` will run its code in the root zone.
    // No need to do anything extra,
    _rootScheduleMicrotask(_rootZone, callback);
    return;
  }
  if (currentZone._scheduleMicrotaskFunction == null &&
      currentZone._handleUncaughtErrorFunction == null) {
    // No overrides of schedule microtask and not in other error zone.
    // Just register.
    _rootScheduleMicrotask(
      currentZone,
      currentZone._registerCallbackZoned(currentZone, callback),
    );
    return;
  }
  // SHOULD NOT BE BINDING!
  // The binding should only happen in `_rootScheduleMicrotask`,
  // as an implementation detail. The wrapped function should not
  // be passed to intermediate `scheduleMicrotask` handlers.
  currentZone._scheduleMicrotaskZoned(
    currentZone,
    currentZone.bindCallbackGuarded(callback),
  );
}