Что относится к микрозадачам (microtask) в Dart?

«Что относится к микрозадачам (microtask) в Dart?» — вопрос из категории Асинхронность, который задают на 36% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Микрозадачи (microtasks) в Dart — это задачи с высшим приоритетом, которые выполняются сразу после текущего синхронного кода, но перед обработкой следующей макрозадачи из очереди событий (event queue). Они планируются в отдельную очередь микрозадач (microtask queue).

Типичные примеры микрозадач:

  • Явное планирование: Через scheduleMicrotask().
  • Завершение Future: Коллбэк, переданный в Future.microtask().
  • Обработчики then, catchError, whenComplete: Выполняются как микрозадачи, если Future уже завершен (has value) в момент вызова then. Если Future еще в ожидании, то then добавит коллбэк в очередь микрозадач на момент завершения Future.

Зачем это нужно? Микрозадачи позволяют выполнить работу асинхронно, но гарантированно до следующего отрисовки кадра (frame). Это критично для обновления состояния перед рендерингом UI, чтобы избежать "мерцания" или состояния гонки.

Пример использования:

void updateStateAndScheduleRebuild() {
  // Критичное обновление данных, которое должно отразиться в следующем кадре
  _someValue = newValue;

  // Планируем микрозадачу, чтобы уведомить слушателей/перестроить UI
  // ДЕЛАЕТСЯ ДО ЛЮБЫХ ОЖИДАЮЩИХ МАКРОЗАДАЧ (например, таймеров, network response)
  scheduleMicrotask(() {
    _controller.add(newValue); // Уведомление Bloc/Cubit или ChangeNotifier
  });
}

Важное предупреждение: Нельзя блокировать очередь микрозадач долгими операциями. Если добавить туда бесконечный цикл или тяжелую синхронную работу, Event Loop не сможет перейти к обработке событий (тапов, анимаций), и приложение "зависнет".