Sobes.tech
Middle

Ce sunt generatorii în Dart (sync* și async*) și cum funcționează?

sobes.tech AI

Răspuns de la AI

Generatorii în Dart sunt funcții care returnează o secvență de valori pe măsură ce sunt generate, nu întregul rezultat deodată. Se folosesc cuvintele cheie sync* pentru generatorii sincroni și async* pentru generatorii asincroni.

Generatorii sincroni (sync*)

Returnează un obiect de tip Iterable. Folosește cuvântul cheie yield pentru a emite valoarea următoare. Fluxul de execuție se întrerupe până când se solicită următoarea valoare (de exemplu, într-un ciclu for-in).

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

Generatorii asincroni (async*)

Returnează un obiect de tip Stream. Folosește cuvântul cheie yield pentru a emite valoarea următoare. De asemenea, utilizează yield* pentru a emite toate valorile altui Stream. Fluxul de execuție se întrerupe și se reia când apare un nou eveniment asincron.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Simulare de lucru asincron
    yield i; // Emite valoarea
  }
}

Cum funcționează:

Când se apelează funcția generator, corpul funcției nu se execută imediat. Se returnează un obiect (fie Iterable, fie Stream). Execuția reală a corpului începe doar când se încearcă obținerea valorii pentru prima dată. Când se ajunge la cuvântul cheie yield, valoarea este transmisă "în exterior" și starea funcției este salvată. Execuția corpului se întrerupe. La următoarea încercare de a obține valoarea, execuția se reia de unde a fost întreruptă, până la următorul yield sau sfârșitul funcției.

Diferențe:

Caracteristică sync* (Sincron) async* (Asincron)
Tipul returnat Iterable Stream
Cuvinte cheie sync*, yield async*, yield, yield*
Utilizarea await Nu se permite Se permite
Pauză Până la solicitarea valorii următoare Până la apariția următorului eveniment asincron