swa*_*log 12 stream reactive-programming dart
我无法理解的简短示例:
Stream<int> getNumbersWithException() async* {
for (var i = 0; i < 10; i++) {
yield i;
if (i == 3) throw Exception();
}
}
Run Code Online (Sandbox Code Playgroud)
与用法:
getNumbersWithException()
.handleError((x) => print('Exception caught for $x'))
.listen((event) {
print('Observed: $event');
});
Run Code Online (Sandbox Code Playgroud)
这将在 3 处停止并输出:
Observed: 0
Observed: 1
Observed: 2
Observed: 3
Exception caught for Exception: foo
Run Code Online (Sandbox Code Playgroud)
从文档(https://dart.dev/tutorials/language/streams)和(https://api.dart.dev/stable/2.9.1/dart-async/Stream/handleError.html)来看,这是这样的预期的,因为抛出的异常将自动关闭流。
我目前认为流是异步数据事件的来源,有时可能是错误事件。从文档和示例来看,这一切看起来都很整洁,但我认为想要处理错误并继续观察数据流是一个正常的用例。我很难编写代码来做到这一点。但是,我可能会做错事。任何见解将不胜感激。
编辑:我可以补充一点,我尝试了各种方法,例如使用流转换器,结果相同:
var transformer = StreamTransformer<int, dynamic>.fromHandlers(
handleData: (data, sink) => sink.add(data),
handleError: (error, stackTrace, sink) =>
print('Exception caught for $error'),
handleDone: (sink) => sink.close(),
);
getNumbersWithException().transform(transformer).listen((data) {
print('Observed: $data');
});
Run Code Online (Sandbox Code Playgroud)
另外,listen()有一个可选参数cancelOnError,看起来很有希望,但它默认为false,所以这里没有雪茄。
lrn*_*lrn 10
生成器方法
Stream<int> getNumbersWithException() async* {
for (var i = 0; i < 10; i++) {
yield i;
if (i == 3) throw Exception();
}
}
Run Code Online (Sandbox Code Playgroud)
当你抛出异常时将终止。工作throw正常,它不会直接将异常添加到流中。因此,它通过循环和方法体传播出去,直到整个方法体以抛出异常结束。此时,未处理的异常将添加到流中,然后流将关闭,因为主体已结束。
因此,问题不在于处理,而在于流的生成。您确实必须在本地处理错误,以避免它结束流生成主体。
throw您不能在方法中使用向流添加多个错误async*,并且该错误将是流执行的最后一件事。
实际上发出多个错误的可用黑客方法是产生异常:
if (i == 3) yield* () async* { throw Exception(); }();
// or: yield* Stream.fromFuture(Future.error(Exception());
// or: yield* Stream.error(Exception()); // Since Dart 2.5
Run Code Online (Sandbox Code Playgroud)
这将直接向生成的流发出异常,而不会在本地抛出异常并结束生成器方法体。
小智 7
使用yield* Stream.error()而不是抛出错误。
例子:
Stream<int> getStream() async* {
for (var i = 0; i < 5; i++) {
yield i;
if (i == 2 || i == 3) {
yield* Stream.error('Custom error at index $i');
}
}
}
void main(List<String> arguments) {
var stream = getStream();
stream.listen((event) => print('Data: $event'),
onDone: () => print('Done'), onError: (err) => print('Error: $err'));
}
Run Code Online (Sandbox Code Playgroud)
输出:
Data: 0
Data: 1
Data: 2
Error: Custom error at index 2
Data: 3
Error: Custom error at index 3
Data: 4
Done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6036 次 |
| 最近记录: |