Sobes.tech
Middle

Was sind Generatoren in Dart (sync* und async*) und wie funktionieren sie?

sobes.tech KI

Antwort von AI

Generatoren in Dart sind Funktionen, die eine Sequenz von Werten zurückgeben, während sie generiert werden, anstatt das gesamte Ergebnis sofort. Es werden die Schlüsselwörter sync* für synchrone Generatoren und async* für asynchrone Generatoren verwendet.

Synchrone Generatoren (sync*)

Geben ein Objekt vom Typ Iterable zurück. Verwenden das Schlüsselwort yield, um den nächsten Wert auszugeben. Der Ausführungsfluss wird pausiert, bis der nächste Wert angefordert wird (z.B. in einer for-in-Schleife).

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

Asynchrone Generatoren (async*)

Geben ein Objekt vom Typ Stream zurück. Verwenden das Schlüsselwort yield, um den nächsten Wert auszugeben. Außerdem verwenden sie yield*, um alle Werte eines anderen Stream auszugeben. Der Ausführungsfluss wird pausiert und bei einem neuen asynchronen Ereignis wieder aufgenommen.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Asynchrone Arbeit simulieren
    yield i; // Wert ausgeben
  }
}

Wie sie funktionieren:

Beim Aufruf der Generatorfunktion wird der Funktionskörper nicht sofort ausgeführt. Es wird ein Objekt (entweder Iterable oder Stream) zurückgegeben. Die tatsächliche Ausführung des Körpers beginnt erst, wenn versucht wird, den Wert zum ersten Mal zu erhalten. Wenn das Schlüsselwort yield erreicht wird, wird der Wert "nach außen" übertragen und der Zustand der Funktion gespeichert. Die Ausführung des Körpers wird pausiert. Beim nächsten Versuch, einen Wert zu erhalten, wird die Ausführung dort wieder aufgenommen, wo sie aufgehört hat, bis zum nächsten yield oder zum Ende der Funktion.

Unterschiede:

Merkmal sync* (Synchron) async* (Asynchron)
Rückgabetyp Iterable Stream
Schlüsselwörter sync*, yield async*, yield, yield*
Verwendung von await Nicht erlaubt Erlaubt
Pausierung Bis die nächste Anfrage erfolgt Bis das nächste asynchrone Ereignis eintritt