Flutter Recovering Stream Errors小技巧
程序员界的小学生 人气:0正文
你是否遇到过,出现异常的时候也需要给一个默认值,让程序可以继续运行下去?
一般的做法就是 一个达到try catch,然后在finally里面做一个处理。
今天我尝试换一个思路,简单的封装一下
简单封装
首先定义一个stream转换器,为了处理error handler。
如果onError不为空,就将出现错误添加到stream中
class StreamErrorHandle<T> extends StreamTransformerBase<T, T> { final _controller = StreamController<T>.broadcast(); final T? Function(Object error) onError; StreamErrorHandler({ required this.onError, }); @override Stream<T> bind(Stream<T> stream) { ... } }
override bind()
用Stream里面的handleError来捕获错误。如果出现错误,我们调用handler,如果我们得到一个返回值,就将他发送到stream
@override Stream<T> bind(Stream<T> stream) { final sub = stream.handleError((error) { final value = onError(error); if (value != null) { _controller.sink.add(value); } }).listen(_controller.sink.add); _controller.onCancel = (){ sub.cancel(); }; return _controller.stream; }
最后我们在Stream上面创建一个拓展,它允许我们轻松的使用我们的流转换器
extension Recover<T> on Stream<T> { Stream<T> onErrorRecoverWith(T? Functioon(Object error) onError) => transform(StreamErrorHandle<T>(onError: onError)); }
测试一下
Stream<String> getNames() async* { yield 'Foo'. yield 'Bar'; throw Exception('Something went wrong'); } Future<void> testIt() async { final names = getNames().onErrorRecoverWith( (error) { error.log(); return 'Baz'; }, ); await for(final name in names){ name.log(); // Foo, Bar, Baz } }
最后来看一下结果:
这里面有一个小注意的地方,log()是我自己封装的一个拓展
import 'dart:developer' as devtools show log; extension Log on Object { void log() => devtools.log(toString()); }
加载全部内容