Stream Controllers
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 78 de 110.
Aunque los generadores async* son excelentes para crear flujos con datos predefinidos, a veces necesitas más control, como añadir datos a un flujo desde distintas partes de tu código. Ahí es donde entra en juego StreamController.
Un StreamController actúa como administrador de un flujo. Te proporciona un «sink» para añadir datos y un «stream» al que los oyentes pueden suscribirse:
import 'dart:async';
void main() {
var controller = StreamController<String>();
// Escuchar el stream
controller.stream.listen((data) {
print('Received: $data');
});
// Agregar datos a través del sink
controller.add('Hello');
controller.add('World');
controller.close(); // Cerrar siempre al terminar
}El método add() inserta nuevos valores en el flujo, y cualquier escucha los recibe inmediatamente. Siempre debes llamar a close() cuando hayas terminado para liberar recursos.
De forma predeterminada, un flujo solo puede tener un oyente. Para varios oyentes, usa un controlador de difusión:
import 'dart:async';
void main() {
var controller = StreamController<int>.broadcast();
controller.stream.listen((n) => print('Listener 1: $n'));
controller.stream.listen((n) => print('Listener 2: $n'));
controller.add(42);
controller.close();
}Los StreamControllers son esenciales en la POO para construir clases orientadas a eventos, como notificar a múltiples partes de su aplicación cuando los datos cambian, manejar acciones del usuario o gestionar actualizaciones en tiempo real dentro de sus objetos.
Desafío
Fácil¡Construyamos un sistema de centro de mensajes que permita que varios suscriptores reciban mensajes en tiempo real! Usarás un StreamController para gestionar el flujo de mensajes y demostrar cómo los streams de difusión permiten varios listeners.
Organizarás tu código en dos archivos:
message_hub.dart: Crea una claseMessageHubque gestione la distribución de mensajes mediante un StreamController. Tu centro debe:- Usar internamente un
StreamController<String>de difusión para que varios listeners puedan suscribirse - Proporcionar un getter llamado
messagesque devuelva el stream al que los listeners puedan suscribirse - Tener un método
broadcast(String message)que añada un mensaje al stream - Tener un método
shutdown()que cierre el controlador
- Usar internamente un
main.dart: Importa tu centro de mensajes y configura un escenario con varios suscriptores escuchando el mismo stream:- Crea una instancia de
MessageHub - Añade un primer listener que imprima los mensajes con el formato:
Subscriber A: [message] - Añade un segundo listener que imprima los mensajes con el formato:
Subscriber B: [message] - Difunde tres mensajes:
Hello everyone,Welcome to the hubyGoodbye - Apaga el centro
- Crea una instancia de
Recuerda importar dart:async en tu archivo del centro de mensajes para acceder a StreamController. Observa cómo ambos suscriptores reciben cada mensaje que se difunde: ¡ese es el poder de los streams de difusión!
Salida esperada:
Subscriber A: Hello everyone
Subscriber B: Hello everyone
Subscriber A: Welcome to the hub
Subscriber B: Welcome to the hub
Subscriber A: Goodbye
Subscriber B: GoodbyePruébalo tú mismo
import 'message_hub.dart';
void main() {
// TODO: Crea una instancia de MessageHub
// TODO: Añade el primer listener que imprima: Subscriber A: [message]
// TODO: Añade el segundo listener que imprima: Subscriber B: [message]
// TODO: Transmite tres mensajes:
// - "Hello everyone"
// - "Welcome to the hub"
// - "Goodbye"
// TODO: Cierra el hub
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online