Menu
Coddy logo textTech

Streams Basics

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 77 of 110.

While a Future delivers a single value, a Stream delivers a sequence of values over time. Think of it like a pipe that can emit multiple pieces of data - perfect for events, real-time updates, or processing data piece by piece.

You can create a simple stream using Stream.fromIterable() or an async generator function with async* and 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

The async* keyword marks a function that returns a Stream, and yield emits each value. To consume the stream, use await for which processes each value as it arrives.

You can also listen to a stream using the listen() method, which takes a callback function:

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

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

The key difference from Futures: a Future completes once with a single value, while a Stream can emit many values before it's done. This makes Streams ideal for handling ongoing data like user interactions, sensor readings, or data arriving in chunks.

challenge icon

Challenge

Easy

Let's build a countdown timer system that emits values over time using streams! You'll create a class that generates a sequence of countdown numbers, demonstrating how streams deliver multiple values rather than just one.

You'll organize your code into two files:

  • countdown.dart: Create a Countdown class that generates countdown streams. Your class should have:
    • A start field (int) that stores the starting number for the countdown
    • A constructor that takes the starting number
    • A method countDown() that returns a Stream<int>. Use async* and yield to emit numbers from start down to 0 (inclusive)
    • A method countDownWithMessage() that returns a Stream<String>. This should emit strings in the format 'T-minus [number]' for each number from start down to 1, then emit 'Liftoff!' as the final value
  • main.dart: Import your countdown file and demonstrate both stream methods. Your main function should be async and:
    • Create a Countdown instance starting from 3
    • Print Number countdown:
    • Use await for to iterate through countDown() and print each number
    • Print an empty line
    • Print Launch sequence:
    • Use await for to iterate through countDownWithMessage() and print each message

Notice how each yield statement emits a value through the stream, and await for processes each value as it arrives. Unlike a Future that delivers one result, your streams will emit multiple values in sequence!

Expected output:

Number countdown:
3
2
1
0

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

Cheat sheet

A Stream delivers a sequence of values over time, unlike a Future which delivers a single value. Streams are ideal for events, real-time updates, or processing data piece by piece.

Create a stream using an async generator function with async* and yield:

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

Consume a stream using await for:

Future<void> main() async {
  await for (var number in countToThree()) {
    print(number);
  }
}

Alternatively, use the listen() method with a callback:

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

You can also create a stream from an iterable using Stream.fromIterable().

Try it yourself

import 'countdown.dart';

Future<void> main() async {
  // TODO: Create a Countdown instance starting from 3
  
  // TODO: Print 'Number countdown:'
  
  // TODO: Use await for to iterate through countDown() and print each number
  
  // TODO: Print an empty line
  
  // TODO: Print 'Launch sequence:'
  
  // TODO: Use await for to iterate through countDownWithMessage() and print each message
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming