Skip to content

Instantly share code, notes, and snippets.

@kaboc
Last active August 7, 2020 06:14
Show Gist options
  • Select an option

  • Save kaboc/5ef2354a1ec50f9378beeef194be07bb to your computer and use it in GitHub Desktop.

Select an option

Save kaboc/5ef2354a1ec50f9378beeef194be07bb to your computer and use it in GitHub Desktop.
Example of utilising `finally` for some processing at the end of `await for` in an `async*` method.
import 'dart:async';
Future<void> main() async {
final controller = StreamController<int>();
final stream = counterStream(controller);
counter(controller);
await stream.forEach(print);
controller.close();
print('main() ended.');
}
Future<void> counter(StreamController<int> controller) async {
for (var i = 1; i <= 5; i++) {
await Future<void>.delayed(const Duration(milliseconds: 200));
controller.sink.add(i);
}
// finally block won't be executed without this line.
await controller.sink.close();
print('counter() ended.');
}
Stream<int> counterStream(StreamController<int> controller) async* {
try {
await for (final value in controller.stream) {
yield value;
}
} finally {
print('counterStream() ended.');
}
}
Copy link

ghost commented Aug 7, 2020

Useful to make sink close when an Exception or Error occurs inside await for loop, (or breaks the loop in some condition).
In a successful case, a sink should be closed by a sender.

import 'dart:async';

Future<void> main() async {
  final controller = StreamController<int>();
  final stream = counterStream(controller);
  counter(controller);

  await stream.forEach(print);

  controller.close();
  print('main() ended.');
}

Future<void> counter(StreamController<int> controller) async {
  for (var i = 1; i <= 5; i++) {
    await Future<void>.delayed(const Duration(milliseconds: 200));
    controller.sink.add(i);
  }

  // finally block won't be executed without this line.
  await controller.sink.close();

  print('counter() ended.');
}

Stream<int> counterStream(StreamController<int> controller) async* {
  try {
    await for (final value in controller.stream) {
      if (value == 3) throw Error();
      yield value;
    }
  } catch (e) {
    print('catch $e');
  } finally {
    print('counterStream() ended.');
    await controller.sink.close();
  }
}

@kaboc
Copy link
Author

kaboc commented Aug 7, 2020

@ntaoo
Your code describes a more concrete usecase and is more helpful. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment