Undefined variable $domain_name
Dart — однопоточный язык с асинхронной моделью выполнения, построенной на event loop. Понимание этой модели отличает мидл-разработчика от джуниора: джуниор просто пишет await и надеется, что всё сработает, а мидл понимает, почему код выполняется именно в таком порядке, и умеет предсказывать поведение программы под нагрузкой.
Главный тезис, который нужно усвоить: Dart-код в рамках одного изолята выполняется в одном потоке. Это означает, что никакие две функции не выполняются одновременно. Параллелизм достигается не потоками, а изолятами (isolates), каждый из которых имеет собственную память и собственный event loop.
Внутри одного изолята concurrency реализуется через очередь событий. Задача разработчика — не блокировать этот поток долгими синхронными операциями, иначе UI зависнет или сервер перестанет отвечать на другие запросы.
Event loop в Dart обрабатывает две очереди в строго определённом порядке:
Алгоритм работы цикла:
Отсюда практическое следствие: микрозадачи всегда имеют приоритет над событиями. Если бесконечно добавлять микрозадачи, event queue никогда не будет обработана — поток зависнет.
Рассмотрим классический пример, который часто спрашивают на собеседовании:
Порядок вывода: A, D, C, B. Сначала весь синхронный код, затем microtask, и только потом event.
Future<T> — это объект, представляющий результат асинхронной операции, который станет доступен позже. У него три состояния: uncompleted, completed with value, completed with error.
Ключевые моменты, которые мидл обязан знать:
Плохой вариант — ловить ошибку через try/catch вокруг await, но забывать про случаи, когда Future не ожидается. Хороший вариант — явно обрабатывать ошибку на границе:
Stream<T> — это последовательность асинхронных событий. Если Future — это одно значение в будущем, то Stream — это много значений, распределённых во времени. Различают два вида:
Мидл должен понимать разницу между StreamController и StreamController.broadcast, а также уметь трансформировать потоки через map, where, asyncMap, transform.
Одна из частых проблем при работе со Stream — backpressure, когда производитель генерирует события быстрее, чем потребитель успевает их обрабатывать. Решения:
Zone — механизм, позволяющий перехватывать и обрабатывать асинхронные ошибки и управлять контекстом выполнения. Фреймворки вроде Flutter используют зоны для перехвата ошибок в кадре рендеринга. Мидл должен знать, что runZonedGuarded позволяет обернуть всё приложение и логировать любые необработанные асинхронные исключения.
Понимание event loop — это фундамент, на котором строятся в