Sobes.tech
Middle

Čo sú generátory v Dart (sync* a async*) a ako fungujú?

sobes.tech AI

Odpoveď od AI

Generátory v Dart sú funkcie, ktoré vracajú sekvenciu hodnôt počas ich generovania, nie celý výsledok naraz. Používajú sa kľúčové slová sync* pre synchronné a async* pre asynchrónne generátory.

Synchronné generátory (sync*)

Vracajú objekt typu Iterable. Používajú kľúčové slovo yield na vydanie ďalšej hodnoty. Prúd vykonávania sa pozastaví, kým nebude požadovaná ďalšia hodnota (napríklad v cykle for-in).

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

Asynchrónne generátory (async*)

Vracajú objekt typu Stream. Používajú kľúčové slovo yield na vydanie ďalšej hodnoty. Tiež používajú yield* na vydanie všetkých hodnôt iného Stream. Prúd vykonávania sa pozastaví a obnoví pri novom asynchrónnom udalosti.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Napodobnenie asynchrónnej práce
    yield i; // Vydanie hodnoty
  }
}

Ako fungujú:

Pri volaní generátora funkcie sa telo funkcie okamžite nevykoná. Vráti sa objekt (buď Iterable, alebo Stream). Skutočné vykonanie tela funkcie začína až pri prvej snahe získať hodnotu z vráteného objektu. Pri dosiahnutí kľúčového slova yield sa hodnota odovzdá "vonku" a stav funkcie sa uloží. Vykonanie tela funkcie sa pozastaví. Pri ďalšej snahe získať hodnotu sa vykonanie obnoví od miesta, kde bolo zastavené, až do ďalšieho yield alebo konca funkcie.

Rozdiely:

Charakteristika sync* (Synchronný) async* (Asynchrónny)
Vrátený typ Iterable Stream
Kľúčové slová sync*, yield async*, yield, yield*
Použitie await Nie Áno
Pozastavenie Pred požiadavkou na ďalšiu hodnotu Pred objavením sa ďalšej asynchrónnej hodnoty