Menu
Coddy logo textTech

Podstawy strumieni

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 77 z 110.

Podczas gdy Future dostarcza pojedynczą wartość, Stream dostarcza sekwencję wartości w czasie. Pomyśl o nim jak o rurze, która może emitować wiele porcji danych — idealnej do obsługi zdarzeń, aktualizacji w czasie rzeczywistym lub przetwarzania danych kawałek po kawałku.

Możesz utworzyć prosty strumień za pomocą Stream.fromIterable() lub funkcji generatora asynchronicznego z użyciem async* i yield:

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

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

Słowo kluczowe async* oznacza funkcję, która zwraca strumień, a yield emituje każdą wartość. Aby odbierać strumień, użyj await for, które przetwarza każdą wartość w miarę jej otrzymywania.

Możesz również nasłuchiwać strumienia za pomocą metody listen(), która przyjmuje funkcję zwrotną:

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

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

Kluczowa różnica w porównaniu z obiektami Future: obiekt Future kończy działanie, zwracając jedną wartość, podczas gdy obiekt Stream może emitować wiele wartości, zanim zakończy działanie. Dzięki temu obiekty Stream idealnie nadają się do obsługi ciągle napływających danych, takich jak interakcje użytkownika, odczyty z czujników czy dane przychodzące w porcjach.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system timera odliczającego, który emituje wartości w czasie za pomocą strumieni! Utworzysz klasę generującą sekwencję liczb odliczania, aby pokazać, jak strumienie dostarczają wiele wartości, a nie tylko jedną.

Podzielisz kod na dwa pliki:

  • countdown.dart: Utwórz klasę Countdown, która generuje strumienie odliczania. Twoja klasa powinna mieć:
    • Pole start (int), które przechowuje początkową liczbę odliczania
    • Konstruktor przyjmujący początkową liczbę
    • Metodę countDown(), która zwraca Stream<int>. Użyj async* i yield, aby emitować liczby od start do 0 (włącznie)
    • Metodę countDownWithMessage(), która zwraca Stream<String>. Powinna emitować ciągi znaków w formacie 'T-minus [number]' dla każdej liczby od start do 1, a następnie wyemitować 'Liftoff!' jako wartość końcową
  • main.dart: Zaimportuj plik z odliczaniem i zademonstruj działanie obu metod strumienia. Twoja funkcja main powinna być asynchroniczna i:
    • Utworzyć instancję Countdown rozpoczynającą od 3
    • Wypisać Number countdown:
    • Użyć await for, aby iterować po countDown() i wypisywać każdą liczbę
    • Wypisać pusty wiersz
    • Wypisać Launch sequence:
    • Użyć await for, aby iterować po countDownWithMessage() i wypisywać każdą wiadomość

Zwróć uwagę, że każda instrukcja yield emituje wartość przez strumień, a await for przetwarza każdą wartość w chwili jej nadejścia. W przeciwieństwie do obiektu Future, który dostarcza jeden wynik, strumienie będą emitować wiele wartości po kolei!

Oczekiwany wynik:

Number countdown:
3
2
1
0

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

Spróbuj swoich sił

import 'countdown.dart';

Future<void> main() async {
  // TODO: Utwórz instancję Countdown, zaczynając od 3
  
  // TODO: Wypisz 'Number countdown:'
  
  // TODO: Użyj await for, aby przejść przez wartości zwracane przez countDown() i wypisać każdą liczbę
  
  // TODO: Wypisz pustą linię
  
  // TODO: Wypisz 'Launch sequence:'
  
  // TODO: Użyj await for, aby przejść przez wartości zwracane przez countDownWithMessage() i wypisać każdy komunikat
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online