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
时,将调用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/