Menu
Coddy logo textTech

Noções básicas de Streams

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 77 de 110.

Enquanto um Future entrega um único valor, um Stream entrega uma sequência de valores ao longo do tempo. Pense nisso como um tubo que pode emitir múltiplos pedaços de dados — perfeito para eventos, atualizações em tempo real ou processamento de dados pedaço por pedaço.

Você pode criar um stream simples usando Stream.fromIterable() ou uma função geradora assíncrona com 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);
  }
}
// Saída: 1, 2, 3

A palavra-chave async* marca uma função que retorna um Stream, e yield emite cada valor. Para consumir o stream, use await for, que processa cada valor à medida que chega.

Você também pode escutar um fluxo usando o método listen(), que recebe uma função de callback:

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

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

A principal diferença em relação às Futures: uma Future é concluída uma vez com um único valor, enquanto um Stream pode emitir muitos valores antes de ser concluído. Isso torna os Streams ideais para lidar com dados contínuos, como interações do usuário, leituras de sensores ou dados que chegam em partes.

challenge icon

Desafio

Fácil

Vamos criar um sistema de temporizador de contagem regressiva que emite valores ao longo do tempo usando fluxos! Você criará uma classe que gera uma sequência de números de contagem regressiva, demonstrando como os fluxos fornecem vários valores em vez de apenas um.

Você organizará seu código em dois arquivos:

  • countdown.dart: crie uma classe Countdown que gere fluxos de contagem regressiva. Sua classe deve ter:
    • Um campo start (int) que armazena o número inicial da contagem regressiva
    • Um construtor que recebe o número inicial
    • Um método countDown() que retorna um Stream<int>. Use async* e yield para emitir números de start até 0 (inclusive)
    • Um método countDownWithMessage() que retorna um Stream<String>. Ele deve emitir strings no formato 'T-minus [number]' para cada número de start até 1, e então emitir 'Liftoff!' como valor final
  • main.dart: importe seu arquivo de contagem regressiva e demonstre os dois métodos de fluxo. Sua função principal deve ser assíncrona e:
    • Criar uma instância de Countdown começando em 3
    • Imprimir Number countdown:
    • Usar await for para iterar por countDown() e imprimir cada número
    • Imprimir uma linha vazia
    • Imprimir Launch sequence:
    • Usar await for para iterar por countDownWithMessage() e imprimir cada mensagem

Observe como cada instrução yield emite um valor por meio do fluxo, e await for processa cada valor conforme ele chega. Diferentemente de um Future, que fornece um único resultado, seus fluxos emitirão vários valores em sequência!

Saída esperada:

Number countdown:
3
2
1
0

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

Experimente você mesmo

import 'countdown.dart';

Future<void> main() async {
  // TODO: Crie uma instância de Countdown começando de 3
  
  // TODO: Imprima 'Number countdown:'
  
  // TODO: Use await for para iterar através de countDown() e imprimir cada número
  
  // TODO: Imprima uma linha vazia
  
  // TODO: Imprima 'Launch sequence:'
  
  // TODO: Use await for para iterar através de countDownWithMessage() e imprimir cada mensagem
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Dart online