Completer în Dart

Creează un Future pe care îl termini tu, manual, mai târziu; leagă codul cu callback-uri de codul cu await.

Sintaxă
import 'dart:async';

abstract interface class Completer<T>
Completer<T>()
Future<T> get future

Ce face Completer

Un Completer are un future care stă în așteptare până când chemi complete(valoare) sau completeError(eroare). Dai completer.future celui care așteaptă, iar tu decizi când și cu ce se termină.

Este util când transformi un API cu callback-uri (de exemplu „cheamă funcția asta când e gata”) într-o funcție care returnează Future, sau când un rezultat vine dintr-un eveniment.

Ce returnează

future returnează mereu același Future<T>, legat de acest completer.

Exemple

Exemplul 1: Din callback în Future

import 'dart:async';

void descarcaCuCallback(String fisier, void Function(String continut) gata) {
  Timer(const Duration(milliseconds: 30), () => gata('conținutul lui $fisier'));
}

Future<String> descarca(String fisier) {
  final completer = Completer<String>();
  descarcaCuCallback(fisier, completer.complete);
  return completer.future;
}

Future<void> main() async {
  print('aștept...');
  print(await descarca('note.txt'));
}

Rezultat

aștept...
conținutul lui note.txt

Exemplul 2: Așteptarea unui eveniment al utilizatorului

import 'dart:async';

class Buton {
  final _apasat = Completer<String>();
  Future<String> get primulClic => _apasat.future;
  void apasa(String cine) {
    if (!_apasat.isCompleted) _apasat.complete(cine);
  }
}

Future<void> main() async {
  final buton = Buton();
  Timer(const Duration(milliseconds: 20), () => buton.apasa('Ana'));
  Timer(const Duration(milliseconds: 40), () => buton.apasa('Mihai'));
  print('Primul clic: ${await buton.primulClic}');
  await Future.delayed(const Duration(milliseconds: 60));
  print('Al doilea clic a fost ignorat.');
}

Rezultat

Primul clic: Ana
Al doilea clic a fost ignorat.

Greșeli frecvente

  • Chemi complete de două ori. A doua oară apare StateError; verifică întâi isCompleted.
  • Uiți să termini completer-ul pe calea de eroare. Cine așteaptă future rămâne blocat pentru totdeauna.

Comenzi înrudite

  • Completer.complete: complete termină future-ul cu o valoare, completeError cu o eroare; isCompleted spune dacă s-a terminat deja.
  • Completer.sync: Completer care anunță ascultătorii imediat, în timpul apelului complete, nu mai târziu.
  • 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.
  • StreamController: Creează un stream pe care îl alimentezi tu: ce pui cu add ajunge la cei care ascultă controller.stream.