asynchronous - 什么时候onDone事件可用于Dart中的StreamSubscription?

标签 asynchronous dart events stream

void sample_stream_1() {
  final myGenerator = NumberCreator();
  final myStream = myGenerator.stream;
  myStream
        .listen(
            (data) => print('Data: $data'),
            onError: (err) => print('Error!'),
            cancelOnError: false,
            onDone: () {
                myGenerator.finish();
                print('Done!');
            },
        );
}

class NumberCreator {
  final _controller = StreamController<int>();
  var _count = 1;

  NumberCreator() {
    Timer.periodic(Duration(seconds: 1), (t) {
      this._controller.sink.add(this._count);
      this._count++;
            if (_count > 10) t.cancel();
    });
  }

  Stream<int> get stream => this._controller.stream;
  void finish() => this._controller.close();
}

main(List<String> args) {
  sample_stream_1();
  print('waiting...');
}
输出为:
[Running] dart "./future_stream_demo.dart"
waiting...
Data: 1
Data: 2
Data: 3
Data: 4
Data: 5
Data: 6
Data: 7
Data: 8
Data: 9
Data: 10

[Done] exited with code=0 in 11.164 seconds
如果我将sample_stream_1()过程更改为此, onDone 事件不会触发:
void sample_stream_1() {
  final myGenerator = NumberCreator();
  final myStream = myGenerator.stream;
  myStream
        .take(5)
        .listen(
            (data) => print('Data: $data'),
            onError: (err) => print('Error!'),
            cancelOnError: false,
            onDone: () {
                myGenerator.finish();
                print('Done!');
            },
        );
}
输出为:
[Running] dart "./future_stream_demo.dart"
waiting...
Data: 1
Data: 2
Data: 3
Data: 4
Data: 5
Done!
Unhandled exception:
Bad state: Cannot add event after closing
#0      _StreamController.add (dart:async/stream_controller.dart:623:24)
#1      _StreamSinkWrapper.add (dart:async/stream_controller.dart:900:13)
#2      new NumberCreator.<anonymous closure> (file:./future_stream_demo.dart:275:29)
#3      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
#4      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
#5      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

[Done] exited with code=255 in 6.298 seconds
触发 onDone 事件,但也会引发异常。
所以:
  • 为什么onDone事件适用于前一个事件而不适用于后一个事件?
  • 为什么后一个异常(exception)?
  • 实现onDone事件的正确方法是什么?
  • 最佳答案

  • 关闭onDone时,将调用Stream回调。在您提供的第一个示例中,您永远不会关闭Stream,因此永远不会调用该回调。如果您在取消计时器的同时调用关闭函数,它将以您期望的方式工作。
    示例:

  • Timer.periodic(Duration(seconds: 1), (t) {
      this._controller.sink.add(this._count);
      this._count++;
            if (_count > 10) {
              t.cancel();
              finish();
            }
    });
    
  • 您正在尝试第二个示例,因为您正在尝试
    向已关闭的Stream添加事件。 5之后
    元素完成后,调用onDone方法,关闭Stream中的NumberCreator,但Timer仍在滴答中,并尝试向关闭的Stream添加事件。这种混淆可能是由于take方法返回的Stream在发出所提供的事件数(在本例中为5)后关闭而导致的。
  • 在大多数情况下,它已经正确地完成了,您永远不会关闭Stream,因此在您认为应该调用它时就永远不会期望它被调用。
  • 关于asynchronous - 什么时候onDone事件可用于Dart中的StreamSubscription?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63784151/

    相关文章:

    vb.net - 在vb.net中异步调用Web服务

    flutter - 如何在 Flutter 中删除两个容器之间的空间?

    dart - Flutter - 我正在寻找一种制作脉冲动画的方法

    javascript - 列出所有事件 Javascript

    javascript - 返回 false 是否可以通过异步函数传递 ESLint 一致返回错误?

    javascript - 如何打破 promise 的链条

    events - 如何在 Google Web Toolkit 中捕获组件的呈现事件?

    php - 使用 PHP 和 MySQL 进行事件编程

    mysql - 存储过程中的 MySQL 临时表与服务器的一次连接的最佳方法

    flutter - Dart 错误 : error: import of dart:mirrors is not supported in the current Dart runtime