Sobes.tech
Middle

Co jsou generátory v Dart (sync* a async*) a jak fungují?

sobes.tech AI

Odpověď od AI

Generátory v Dartu jsou funkce, které vracejí posloupnost hodnot, jak jsou generovány, místo aby vracely celý výsledek najednou. Používají se klíčová slova sync* pro synchronní generátory a async* pro asynchronní generátory.

Synchronní generátory (sync*)

Vrací objekt typu Iterable. Používají klíčové slovo yield k emitování další hodnoty. Tok provádění je pozastaven, dokud není požadována další hodnota (například v cyklu for-in).

Iterable<int> countUpTo(int max) sync* {
  for (int i = 1; i <= max; i++) {
    yield i; // Emitování hodnoty
  }
}

Asynchronní generátory (async*)

Vrací objekt typu Stream. Používají klíčové slovo yield k emitování další hodnoty. Také používají yield* k emitování všech hodnot z jiného Stream. Tok provádění je pozastaven a pokračuje, když se objeví nový asynchronní událost.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Simulace asynchronní práce
    yield i; // Emitování hodnoty
  }
}

Jak fungují:

Při volání generátorové funkce se tělo funkce ihned nevykoná. Vrací se objekt (buď Iterable, nebo Stream). Skutečné provádění těla začíná až při pokusu získat hodnotu poprvé. Když se dosáhne klíčového slova yield, hodnota je "předána ven" a stav funkce je uložen. Provádění těla je pozastaveno. Při dalším pokusu získat hodnotu se provádění obnoví tam, kde bylo přerušeno, až do dalšího yield nebo konce funkce.

Rozdíly:

Charakteristika sync* (Synchronní) async* (Asynchronní)
Vrácený typ Iterable Stream
Klíčová slova sync*, yield async*, yield, yield*
Použití await Není povoleno Je povoleno
Pozastavení Do požadavku na další hodnotu Do objevení se dalšího asynchronního události