Menu
Coddy logo textTech

Nozioni di base sugli stream

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 77 di 110.

Mentre un Future restituisce un singolo valore, uno Stream restituisce una sequenza di valori nel tempo. Pensalo come a un tubo che può emettere più elementi di dati: perfetto per gli eventi, gli aggiornamenti in tempo reale o l’elaborazione dei dati un elemento alla volta.

Puoi creare uno stream semplice usando Stream.fromIterable() oppure una funzione generatrice asincrona con async* e yield:

Stream<int> countToThree() async* {
  yield 1;
  yield 2;
  yield 3;
}

Future<void> main() async {
  await for (var number in countToThree()) {
    print(number);
  }
}
// Output: 1, 2, 3

La parola chiave async* contrassegna una funzione che restituisce uno Stream, e yield emette ogni valore. Per consumare lo stream, usa await for, che elabora ogni valore man mano che arriva.

Puoi anche ascoltare uno stream usando il metodo listen(), che accetta una funzione di callback:

Stream<String> greetings() async* {
  yield 'Hello';
  yield 'Hi';
  yield 'Hey';
}

void main() {
  greetings().listen((message) {
    print(message);
  });
}

La differenza fondamentale rispetto ai Future: un Future si completa una sola volta con un singolo valore, mentre uno Stream può emettere molti valori prima di terminare. Questo rende gli Stream ideali per gestire dati continui come le interazioni degli utenti, le letture dei sensori o i dati che arrivano in blocchi.

challenge icon

Sfida

Facile

Creiamo un sistema di timer per il conto alla rovescia che emette valori nel tempo usando gli stream! Creerai una classe che genera una sequenza di numeri per il conto alla rovescia, mostrando come gli stream forniscano più valori invece di uno solo.

Organizzerai il codice in due file:

  • countdown.dart: crea una classe Countdown che genera stream per il conto alla rovescia. La classe dovrebbe avere:
    • Un campo start (int) che memorizza il numero di partenza del conto alla rovescia
    • Un costruttore che accetta il numero di partenza
    • Un metodo countDown() che restituisce uno Stream<int>. Usa async* e yield per emettere numeri da start fino a 0 (incluso)
    • Un metodo countDownWithMessage() che restituisce uno Stream<String>. Dovrebbe emettere stringhe nel formato 'T-minus [number]' per ogni numero da start fino a 1, poi emettere 'Liftoff!' come valore finale
  • main.dart: importa il file del conto alla rovescia e mostra entrambi i metodi dello stream. La funzione main dovrebbe essere async e:
    • Creare un'istanza di Countdown con valore iniziale 3
    • Stampare Number countdown:
    • Usare await for per iterare su countDown() e stampare ogni numero
    • Stampare una riga vuota
    • Stampare Launch sequence:
    • Usare await for per iterare su countDownWithMessage() e stampare ogni messaggio

Nota come ogni istruzione yield emetta un valore attraverso lo stream e await for elabori ogni valore man mano che arriva. A differenza di un Future, che fornisce un solo risultato, i tuoi stream emetteranno più valori in sequenza!

Output previsto:

Number countdown:
3
2
1
0

Launch sequence:
T-minus 3
T-minus 2
T-minus 1
Liftoff!

Provalo tu

import 'countdown.dart';

Future<void> main() async {
  // TODO: Crea un'istanza di Countdown che inizi da 3
  
  // TODO: Stampa 'Number countdown:'
  
  // TODO: Usa await for per iterare su countDown() e stampare ogni numero
  
  // TODO: Stampa una riga vuota
  
  // TODO: Stampa 'Launch sequence:'
  
  // TODO: Usa await for per iterare su countDownWithMessage() e stampare ogni messaggio
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online