[英]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事件被觸發,但它也會引發異常。
所以:
Stream
關閉時調用onDone
回調。 在您提供的第一個示例中,您永遠不會關閉Stream
,因此永遠不會調用回調。 如果您在定時器取消的同時調用關閉函數,它會按您預期的方式工作。 例子:Timer.periodic(Duration(seconds: 1), (t) {
this._controller.sink.add(this._count);
this._count++;
if (_count > 10) {
t.cancel();
finish();
}
});
Stream
添加事件。 在 5 個獲取的元素完成后,您的onDone
方法被調用,從NumberCreator
關閉Stream
,但Timer
仍在滴答作響,並嘗試將事件添加到關閉的Stream
。 混淆可能來自這樣一個事實,即take
方法返回一個Stream
,該Stream
在發出提供的事件數量后關閉,在本例中為 5。Stream
因此永遠不會在您認為應該調用時調用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.