पाठ 17 / 25

Streams

Consume and create streams of asynchronous events.

Many values over time

A Stream<T> delivers a sequence of asynchronous events: user input, WebSocket messages, file chunks, database change notifications, location updates. Consume a stream with await for inside an async function, or with listen, which returns a StreamSubscription you can pause, resume and cancel (always cancel subscriptions you no longer need to avoid leaks, for example in a Flutter widget's dispose). Single-subscription streams (the default, such as reading a file) allow one listener; broadcast streams allow many listeners and suit events such as UI notifications. Streams have collection-like operators: map, where, take, skip, distinct, asyncMap, expand and handleError. Create streams with async* generator functions that yield values, or with a StreamController that you add events to, close when finished, and expose via its stream property. Packages such as rxdart add more operators, and Flutter's StreamBuilder rebuilds widgets as events arrive.

A stream generator, a controller and await for

async* yields values over time; controllers bridge callback code.

import 'dart:async';

Stream<int> countdown(int from) async* {
  for (var i = from; i >= 0; i--) {
    await Future<void>.delayed(const Duration(seconds: 1));
    yield i;                                 // emit the next value
  }
}

class CartEvents {
  final _controller = StreamController<String>.broadcast();
  Stream<String> get stream => _controller.stream;

  void itemAdded(String sku) => _controller.add('added $sku');
  Future<void> dispose() => _controller.close();
}

Future<void> main() async {
  await for (final seconds in countdown(3)) {
    print('Sale starts in $seconds');
  }

  final events = CartEvents();
  final subscription = events.stream
      .where((e) => e.startsWith('added'))
      .listen((e) => print('Event: $e'));

  events.itemAdded('pen');
  events.itemAdded('ink');
  await Future<void>.delayed(Duration.zero);   // let events be delivered
  await subscription.cancel();                  // always cancel when done
  await events.dispose();
}

A newspaper subscription

A Future is a single parcel you are waiting for. A Stream is a newspaper subscription: issues keep arriving until the publisher stops, and you should cancel the subscription when you move away.

त्वरित जाँच: What does an async* function return?

  • A Future
  • A Stream, emitting values with yield
  • A List
  • An Isolate
Answer

A Stream, emitting values with yield — async* generators produce streams; sync* generators produce iterables.