Dart Stream的listen()没有调用onDone

Nat*_*son 4 dart dart-io

我有一个带变压器的流,它融合UTF8.decoderLineSplitter.它工作得很好,但从不调用onDone参数中指定的函数.

import 'dart:async';
import 'dart:io';
import 'dart:convert';

void main(List<String> arguments) {

  Stream<List<int>> stream = new File("input.txt").openRead();

  stream.transform(UTF8.decoder.fuse(const LineSplitter()))
      .listen((line) {
        stdout.writeln(line);            
      }, onDone: () {
          stdout.write("done");
      }).asFuture().catchError((_) => print(_));
}
Run Code Online (Sandbox Code Playgroud)

任何想法为什么永远不会被调用?

mez*_*oni 6

import 'dart:async';
import 'dart:io';
import 'dart:convert';

void main(List<String> arguments) {

  Stream<List<int>> stream = new File("input.txt").openRead();

  stream.transform(UTF8.decoder.fuse(const LineSplitter()))
      .listen((line) {
        stdout.writeln(line);
      }, onDone: () {
          stdout.write("done");
      }); //.asFuture().catchError((_) => print(_));
}
Run Code Online (Sandbox Code Playgroud)
/**
   * Returns a future that handles the [onDone] and [onError] callbacks.
   *
   * This method *overwrites* the existing [onDone] and [onError] callbacks
   * with new ones that complete the returned future.
   *
   * In case of an error the subscription will automatically cancel (even
   * when it was listening with `cancelOnError` set to `false`).
   *
   * In case of a `done` event the future completes with the given
   * [futureValue].
   */
  Future asFuture([var futureValue]);
Run Code Online (Sandbox Code Playgroud)

返回处理[onDone]和[onError]回调的未来.

此方法使用完成返回的未来的新回调覆盖现有的[onDone]和[onError]回调.

那么,回答:

import 'dart:async';
import 'dart:io';
import 'dart:convert';

void main(List<String> arguments) {

  Stream<List<int>> stream = new File("input.txt").openRead();

  stream.transform(UTF8.decoder.fuse(const LineSplitter()))
      .listen((line) {
        stdout.writeln(line);
      }, onDone: () {
          stdout.write("Not wait me, because 'asFuture' overwrites me");
      }).asFuture().catchError((_) => print(_))
      .whenComplete(() => stdout.write("done"));
}
Run Code Online (Sandbox Code Playgroud)


小智 1

问题是你使用了这个asFuture()方法。

如果你不使用它,onDone当到达 EOF 时将被正确调用;否则,您应该在返回值.then((_) => print('done'))后面加上以获得相同的效果。FutureasFuture()

结果代码应如下所示:

(stream
    .transform(utf8.decoder)
    .transform(LineSplitter())
    .listen((line) => print(line))
    .asFuture())
        .then((_) => print("done"))
        .catchError((err) => stderr.writeln(err));
Run Code Online (Sandbox Code Playgroud)