StreamController.hasListener în Dart

hasListener spune dacă stream-ul controller-ului este ascultat acum; isClosed dacă s-a chemat deja close.

Sintaxă
bool get hasListener
bool get isClosed

Ce face StreamController.hasListener

hasListener este true cât timp există un ascultător (nu a anulat abonamentul). Poți evita munca inutilă: nu produci date dacă nu le ascultă nimeni.

isClosed devine true imediat după close(). Verifică-l înainte de add când nu ești sigur că stream-ul este încă deschis.

Ce returnează

bool, în ambele cazuri.

Exemple

Exemplul 1: Starea controller-ului pas cu pas

import 'dart:async';

Future<void> main() async {
  final c = StreamController<int>();
  print('la început: hasListener=${c.hasListener}, isClosed=${c.isClosed}');

  final abonament = c.stream.listen((_) {});
  print('după listen: hasListener=${c.hasListener}');

  await abonament.cancel();
  print('după cancel: hasListener=${c.hasListener}');

  unawaited(c.close());
  print('după close: isClosed=${c.isClosed}');
}

Rezultat

la început: hasListener=false, isClosed=false
după listen: hasListener=true
după cancel: hasListener=false
după close: isClosed=true

Exemplul 2: Trimite doar dacă e cineva și dacă e deschis

import 'dart:async';

class Notificari {
  final _c = StreamController<String>.broadcast();
  Stream<String> get stream => _c.stream;

  void trimite(String mesaj) {
    if (_c.isClosed) {
      print('(închis, ignor "$mesaj")');
    } else if (!_c.hasListener) {
      print('(nimeni nu ascultă, ignor "$mesaj")');
    } else {
      _c.add(mesaj);
    }
  }

  Future<void> inchide() => _c.close();
}

Future<void> main() async {
  final n = Notificari();
  n.trimite('mesaj pierdut');
  final ascultare = n.stream.listen((m) => print('primit: $m'));
  n.trimite('Comanda a plecat');
  await Future.delayed(Duration.zero);
  await ascultare.cancel();
  await n.inchide();
  n.trimite('prea târziu');
}

Rezultat

(nimeni nu ascultă, ignor "mesaj pierdut")
primit: Comanda a plecat
(închis, ignor "prea târziu")

Greșeli frecvente

  • Crezi că hasListener devine false când ascultătorul pune pauză. Rămâne true; pentru pauză folosește isPaused sau onPause.

Comenzi înrudite

  • StreamController: Creează un stream pe care îl alimentezi tu: ce pui cu add ajunge la cei care ascultă controller.stream.
  • StreamController.add: add trimite o valoare în stream, addError trimite o eroare, iar close trimite semnalul de final.
  • StreamController.broadcast: Controller al cărui stream poate avea oricâți ascultători; fiecare primește evenimentele trimise cât timp ascultă.