Назад к вопросам
Middle
136
questionbank

Что такое генераторы в Dart (sync* и async*) и как они работают?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Генераторы в Dart – это функции, которые возвращают последовательность значений по мере их генерации, а не весь результат сразу. Используются ключевые слова sync* для синхронных и async* для асинхронных генераторов.

Синхронные генераторы (sync*)

Возвращают объект типа Iterable. Используют ключевое слово yield для выдачи следующего значения. Поток выполнения приостанавливается до тех пор, пока следующее значение не будет запрошено (например, в цикле for-in).

Iterable<int> countUpTo(int max) sync* {
  for (int i = 1; i <= max; i++) {
    yield i; // Выдача значения
  }
}

Асинхронные генераторы (async*)

Возвращают объект типа Stream. Используют ключевое слово yield для выдачи следующего значения. Так же используют yield* для выдачи всех значений другого Stream. Поток выполнения приостанавливается и возобновляется при наличии нового асинхронного события.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Имитация асинхронной работы
    yield i; // Выдача значения
  }
}

Как они работают:

При вызове функции-генератора, тело функции сразу не исполняется. Возвращается объект (либо Iterable, либо Stream). Фактическое исполнение тела функции начинается только при первой попытке получить значение из возвращенного объекта. При достижении ключевого слова yield, значение передается "наружу", а состояние функции сохраняется. Исполнение тела функции приостанавливается. При следующей попытке получить значение, исполнение возобновляется с места, где оно было остановлено, до следующего yield или окончания функции.

Отличия:

Характеристика sync* (Синхронный) async* (Асинхронный)
Возвращаемый тип Iterable Stream
Ключевые слова sync*, yield async*, yield, yield*
Использование await Нельзя Можно
Приостановка До запроса следующего значения До появления следующего асинхронного значения