簡體   English   中英

什么時候 onDone 事件對 Dart 中的 StreamSubscription 起作用?

[英]When does onDone event work for StreamSubscription in Dart?

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

onDone事件不會觸發,如果我將sample_stream_1()過程更改為:

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事件被觸發,但它也會引發異常。

所以:

  1. 為什么 onDone 事件適用於前一個而不適用於后一個?
  2. 為什么我在后一個中得到異常?
  3. 實現 onDone 事件的正確方法是什么?
  1. Stream關閉時調用onDone回調。 在您提供的第一個示例中,您永遠不會關閉Stream ,因此永遠不會調用回調。 如果您在定時器取消的同時調用關閉函數,它會按您預期的方式工作。 例子:
Timer.periodic(Duration(seconds: 1), (t) {
  this._controller.sink.add(this._count);
  this._count++;
        if (_count > 10) {
          t.cancel();
          finish();
        }
});
  1. 第二個示例出現異常,因為您嘗試向已關閉的Stream添加事件。 在 5 個獲取的元素完成后,您的onDone方法被調用,從NumberCreator關閉Stream ,但Timer仍在滴答作響,並嘗試將事件添加到關閉的Stream 混淆可能來自這樣一個事實,即take方法返回一個Stream ,該Stream在發出提供的事件數量后關閉,在本例中為 5。
  2. 它已經在大多數情況下正確完成,您只是從不關閉Stream因此永遠不會在您認為應該調用時調用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM