Stream.listen în Dart

Începe ascultarea unui stream: o funcție pentru fiecare valoare, una pentru erori, una pentru final.

Sintaxă
StreamSubscription<T> listen(void onData(T event)?, {Function? onError, void onDone()?, bool? cancelOnError})

Ce face Stream.listen

listen este modul de bază de a primi evenimentele unui stream; await for și metodele ca toList îl folosesc în spate. Primești un StreamSubscription, prin care poți pune pauză sau anula ascultarea.

onData se cheamă pentru fiecare valoare, onError pentru fiecare eroare, iar onDone o dată, la închiderea stream-ului. Cu cancelOnError: true, prima eroare oprește ascultarea. Spre deosebire de await for, listen nu blochează funcția: codul de după el rulează imediat.

Parametri

Parametru Descriere
onData Funcția chemată cu fiecare valoare.
onError Opțional: funcția chemată cu fiecare eroare (eroarea și, opțional, stiva).
onDone Opțional: funcția chemată când stream-ul se închide.
cancelOnError Opțional: dacă e true, ascultarea se oprește la prima eroare.

Ce returnează

Un StreamSubscription<T>.

Exemple

Exemplul 1: Date, erori și final

import 'dart:async';

Stream<String> mesaje() async* {
  yield 'Bună!';
  yield 'Ce faci?';
  throw const FormatException('mesaj corupt');
}

Future<void> main() async {
  final gata = Completer<void>();
  mesaje().listen(
    (m) => print('mesaj: $m'),
    onError: (Object e) => print('eroare: $e'),
    onDone: () {
      print('conversație încheiată');
      gata.complete();
    },
  );
  print('listen nu blochează: rulez imediat');
  await gata.future;
}

Rezultat

listen nu blochează: rulez imediat
mesaj: Bună!
mesaj: Ce faci?
eroare: FormatException: mesaj corupt
conversație încheiată

Exemplul 2: cancelOnError oprește la prima eroare

Future<void> main() async {
  final s = Stream<int>.multi((c) {
    c.add(1);
    c.addError(StateError('senzor deconectat'));
    c.add(2);
    c.close();
  });
  final abonament = s.listen(
    (v) => print('valoare $v'),
    onError: (Object e) => print('eroare: $e'),
    cancelOnError: true,
  );
  await Future.delayed(const Duration(milliseconds: 20));
  print('valoarea 2 nu a mai ajuns');
  await abonament.cancel();
}

Rezultat

valoare 1
eroare: Bad state: senzor deconectat
valoarea 2 nu a mai ajuns

Greșeli frecvente

  • Nu dai onError și stream-ul emite o eroare. Eroarea devine netratată și poate opri programul.
  • Crezi că programul așteaptă după listen. Nu așteaptă; dacă ai nevoie de rezultat, folosește await for, asFuture sau un Completer.

Comenzi înrudite

  • StreamSubscription: Abonamentul returnat de listen; prin el pui pauză, reiei sau anulezi ascultarea unui stream (cancel).
  • StreamSubscription.asFuture: Dă un Future care se termină când stream-ul se termină, sau cu eroare la prima eroare din stream.
  • Stream: Un șir de valori care sosesc în timp, una după alta (mesaje, clicuri, linii dintr-un fișier); îl parcurgi cu await for.
  • await for: Parcurge un Stream element cu element, așteptând fiecare eveniment; se termină când stream-ul se închide.
  • Stream.forEach: Cheamă o funcție pentru fiecare valoare din stream și dă un Future care se termină la închiderea stream-ului.