Ce face await for
await for este bucla for-in pentru stream-uri. Pentru fiecare valoare care sosește, corpul buclei rulează o dată; între valori, funcția așteaptă fără să blocheze programul. Bucla se termină când stream-ul se închide.
Ca orice await, poate fi folosit doar într-o funcție async sau async*. break și return opresc ascultarea (abonamentul este anulat), iar o eroare din stream se aruncă la bucla await for și se prinde cu try.
Nu folosi await for pe stream-uri care nu se închid niciodată (de exemplu clicurile dintr-o interfață), pentru că bucla nu se mai termină. Acolo se folosește stream.listen(...).
Exemple
Exemplul 1: Suma valorilor dintr-un stream
Stream.periodic produce o valoare la fiecare 100 ms; take(4) închide stream-ul după patru valori.
Future<void> main() async {
final incasari = Stream.periodic(const Duration(milliseconds: 100), (i) => (i + 1) * 50).take(4);
var total = 0;
await for (final suma in incasari) {
total += suma;
print('Încasat $suma lei, total $total lei');
}
print('Ziua s-a încheiat.');
}
Rezultat
Încasat 50 lei, total 50 lei
Încasat 100 lei, total 150 lei
Încasat 150 lei, total 300 lei
Încasat 200 lei, total 500 lei
Ziua s-a încheiat.
Exemplul 2: Oprire cu break
Căutarea se oprește la primul rezultat găsit; restul stream-ului nu mai este citit.
Stream<String> clienti() async* {
for (final nume in ['Ana', 'Bogdan', 'Cezar', 'Diana', 'Eugen']) {
await Future.delayed(const Duration(milliseconds: 50));
print(' (citesc $nume)');
yield nume;
}
}
Future<void> main() async {
await for (final nume in clienti()) {
if (nume.startsWith('C')) {
print('Găsit: $nume');
break;
}
}
print('Căutare terminată.');
}
Rezultat
(citesc Ana)
(citesc Bogdan)
(citesc Cezar)
Găsit: Cezar
Căutare terminată.
Exemplul 3: Liniile unui fișier
File.openRead dă un stream de octeți; după decodare și împărțire pe linii, fiecare linie se procesează pe rând, fără să încărcăm tot fișierul în memorie.
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
final fisier = File('vanzari.csv');
await fisier.writeAsString('Cluj;1200\nIași;950\nSibiu;700\n');
var total = 0;
final linii = fisier.openRead().transform(utf8.decoder).transform(const LineSplitter());
await for (final linie in linii) {
final [oras, suma] = linie.split(';');
total += int.parse(suma);
print('$oras: $suma lei');
}
print('Total: $total lei');
}
Rezultat
Cluj: 1200 lei
Iași: 950 lei
Sibiu: 700 lei
Total: 2850 lei
Greșeli frecvente
await forîntr-o funcție fărăasync: eroare de compilare.for (final x in stream)fărăawait: eroare,Streamnu esteIterable.await forpe un stream infinit fărăbreaksautake: codul de după buclă nu se mai execută.
Comenzi înrudite
async*: O funcție async* produce un Stream: trimite valori cu yield, în timp, și poate folosi await între ele.async și await: async marchează o funcție asincronă (întoarce Future), iar await așteaptă rezultatul unui Future fără să blocheze programul.for-in: Parcurge pe rând elementele unei liste, unui set sau oricărui Iterable, fără indice.break și continue: break oprește bucla imediat; continue sare peste restul repetării curente și trece la următoarea.