Sobes.tech
Middle

Kas yra generatoriai Dart (sync* ir async*) ir kaip jie veikia?

sobes.tech AI

Atsakymas iš AI

Dart'e generatoriai yra funkcijos, kurios grąžina reikšmių seką jų generavimo metu, o ne visą rezultatą iš karto. Naudojami raktiniai žodžiai sync* sinchroniniams ir async* asinchroniniams generatoriams.

Sinchroniniai generatoriai (sync*)

Grąžina Iterable tipo objektą. Naudojamas raktinis žodis yield norint išduoti kitą reikšmę. Vykdymo srautas yra sustabdytas iki tol, kol nebus paprašyta kitos reikšmės (pavyzdžiui, for-in cikle).

Iterable<int> countUpTo(int max) sync* {
  for (int i = 1; i <= max; i++) {
    yield i; // Reikšmės išdavimas
  }
}

Asinchroniniai generatoriai (async*)

Grąžina Stream tipo objektą. Naudojamas raktinis žodis yield norint išduoti kitą reikšmę. Taip pat naudojamas yield* norint išduoti visas kito Stream reikšmes. Vykdymo srautas yra sustabdytas ir atnaujinamas, kai atsiranda naujas asinchroninis įvykis.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Asinchroninio darbo imitacija
    yield i; // Reikšmės išdavimas
  }
}

Kaip jie veikia:

Kviečiant generatoriaus funkciją, jos kūnas iš karto nevykdomas. Grąžomas objektas (arba Iterable, arba Stream). Faktinis vykdymas prasideda tik pirmo reikšmės gavimo metu. Pasiekus yield, reikšmė perduodama "išorėje", o funkcijos būsena išsaugoma. Vykdymas yra sustabdytas. Kai kitą kartą bandoma gauti reikšmę, vykdymas atnaujinamas nuo sustojimo vietos iki kito yield arba funkcijos pabaigos.

Skirtumai:

Savybė sync* (Sinchroninis) async* (Asinchroninis)
Grąžinamas tipas Iterable Stream
Raktiniai žodžiai sync*, yield async*, yield, yield*
await naudojimas Negalima Gali būti
Sustojimas Iki kito reikšmės užklausimo Iki naujo asinchroninio įvykio atsiradimo