Difference between await for and listen in Dart Difference between await for and listen in Dart dart dart

Difference between await for and listen in Dart


Given:

Stream<String> stream = new Stream<String>.fromIterable(['mene', 'mene', 'tekel', 'parsin']);

then:

print('BEFORE');stream.listen((s) { print(s); });print('AFTER');

yields:

BEFOREAFTERmenemenetekelparsin

whereas:

print('BEFORE');await for(String s in stream) { print(s); }print('AFTER');

yields:

BEFOREmenemenetekelparsinAFTER

stream.listen() sets up code that will be put on the event queue when an event arrives, then following code is executed.

await for suspends between events and keeps doing so until the stream is done, so code following it will not be executed until that happens.

I use `await for when I have a stream that I know will have finite events, and I need to process them before doing anything else (essentially as if I'm dealing with a list of futures).

Check https://www.dartlang.org/articles/language/beyond-async for a description of await for.


The main difference is when there's code afterwards. listen only register the handler and the execution continue. await for will retain execution until the stream is closed.

Thus if you add a print('hello'); at the end of your main you shouldn't see hello in the output with await for (because the request stream is never closed). Try the following code on dartpad to see the differences :

import 'dart:async';main() async {  tenInts.listen((i) => print('int $i'));  //await for (final i in tenInts) {  //  print('int $i');  //}  print('hello');}Stream<int> get tenInts async* {  for (int i = 1; i <= 10; i++) yield i;}


A more imporant difference is that await for serializes the consumption of the stream items while listen will process them concurrently.

For example the code below:

import 'dart:async';Future<void> process(int i) async {  print("start $i");  await new Future.delayed(const Duration(seconds: 1));  print("end $i");}main() async {  await for (final i in tenInts) {    await process(i);  }  tenInts.listen((i) async => await process(i));  print('hello');}Stream<int> get tenInts async* {  for (int i = 1; i <= 10; i++) yield i;}

yields

start 1end 1start 2end 2start 3end 3start 4end 4start 5end 5start 6end 6start 7end 7start 8end 8start 9end 9start 10end 10hellostart 1start 2start 3start 4start 5start 6start 7start 8start 9start 10end 1end 2end 3end 4end 5end 6end 7end 8end 9end 10