Ce face Future.wait
Future.wait(lista) pornește așteptarea tuturor deodată și se termină când s-au terminat toate. Rezultatul este o listă cu valorile, în aceeași ordine ca future-urile, nu în ordinea terminării. Durata totală este cât cea mai lentă operație, nu suma lor.
Dacă unul eșuează, wait se termină cu acea eroare. Cu eagerError: true, eroarea vine imediat, fără să mai aștepte restul. Pentru future-uri de tipuri diferite, Dart 3 are și forma cu records: final (a, b) = await (f1, f2).wait;.
Future.any(lista) se termină cu rezultatul (sau eroarea) primului future care se termină. Restul continuă, dar rezultatele lor sunt ignorate.
Parametri
| Parametru | Descriere |
|---|---|
futures |
Future-urile așteptate. |
eagerError |
Pentru wait: dacă e true, prima eroare oprește imediat așteptarea. |
cleanUp |
Pentru wait: funcție chemată cu valorile reușite dacă vreun future a eșuat. |
Ce returnează
wait: un Future<List<T>>. any: un Future<T> cu primul rezultat.
Exemple
Exemplul 1: Trei cereri în paralel
Cererile durează 120, 60 și 90 ms. Cu wait, totul durează cât cea mai lentă, iar ordinea rezultatelor este cea din listă.
Future<int> temperatura(String oras, int ms) =>
Future.delayed(Duration(milliseconds: ms), () => oras.length * 5);
Future<void> main() async {
final ceas = Stopwatch()..start();
final rezultate = await Future.wait([
temperatura('Iași', 120),
temperatura('Cluj', 60),
temperatura('Constanța', 90),
]);
print(rezultate);
print('Sub 300 ms în total: ${ceas.elapsedMilliseconds < 300}');
final (nume, varsta) = await (Future.value('Ana'), Future.value(21)).wait;
print('$nume are $varsta ani');
}
Rezultat
[20, 20, 45]
Sub 300 ms în total: true
Ana are 21 ani
Exemplul 2: Primul server care răspunde, cu Future.any
Future<String> server(String nume, int ms) =>
Future.delayed(Duration(milliseconds: ms), () => nume);
Future<void> main() async {
final primul = await Future.any([
server('server-București', 80),
server('server-Frankfurt', 30),
server('server-Amsterdam', 60),
]);
print('A răspuns primul: $primul');
}
Rezultat
A răspuns primul: server-Frankfurt
Exemplul 3: O eroare în Future.wait
Future<int> stoc(String produs) async {
await Future.delayed(const Duration(milliseconds: 10));
if (produs == 'kiwi') throw StateError('$produs nu există');
return produs.length;
}
Future<void> main() async {
try {
await Future.wait([stoc('mere'), stoc('kiwi'), stoc('pere')]);
} on StateError catch (e) {
print('Eroare: ${e.message}');
}
}
Rezultat
Eroare: kiwi nu există
Greșeli frecvente
- Aștepți pe rând, cu
awaitîntr-o buclă, operații care nu depind una de alta. Durata se adună; cuFuture.waitrulează în paralel. - Crezi că lista rezultatelor este în ordinea terminării. Este în ordinea future-urilor din listă.
Comenzi înrudite
Future: O valoare care va fi gata mai târziu (citirea unui fișier, un răspuns de la server); o aștepți cu await.Future.forEach: forEach rulează o acțiune asincronă pe rând pentru fiecare element; doWhile repetă o acțiune cât timp returnează true.Future.timeout: Limitează cât aștepți un future: după timpul dat, aruncă TimeoutException sau folosește onTimeout.records: Grupuri de valori anonime și imutabile, de forma (a, b) sau (nume: a), ideale pentru a întoarce mai multe valori.