【发布时间】:2021-12-18 07:16:55
【问题描述】:
我正在使用dart:io的HTTP客户端下载大文件,方式如下:
final url = Uri.parse(fileUrl);
final request = await httpClient.getUrl(url);
final response = await request.close();
然后我使用HttpClientResponse 类型的response 实现Stream<List<int>>,其中每个发出的List<int> 代表正在下载的文件块。
我的目标是将该流“转换”为另一个流,为此,我最近了解到await for + yield 可以做到这一点:
Stream<Event> processResponse(HttpClientResponse response) async* {
await for (final List<int> chunk in response) {
yield Event.FileChunk(chunk: chunk);
}
yield const Event.Completed();
}
最初,在了解await for之前,我打算使用Stream<T>.listen方法,它接受4个参数:
-
onData回调用于流中每个发出的值, -
onError回调,用于在发出值时通知错误, - 通知流的
onDone回调正在关闭并且不会发出任何新值,最后 -
cancelOnError自解释的布尔参数。
通过使用await for () {},我相信我涵盖了#1 和#3,因为我将获得所有发出的值,完成后,代码将离开await for 的范围,这应该意味着它已经完成。
但是错误呢?由于这些流将是冗长且繁重的 IO 流,因此肯定随时可能出现 IO 错误。他们是如何报道的?我如何访问他们的数据以报告这些数据并在需要时进行调试?
【问题讨论】:
-
如果您想“转换”
Stream,请使用Stream.map/Stream.transform方法,更多信息请点击此处:Methods that modify a stream -
谢谢!似乎
map起到了作用,因为文档说:Error and done events are passed through unchanged to the returned stream,这意味着我可以在收听转换后的流时捕捉到它们。但是,StreamTransformer似乎可以让我更好地控制错误,特别是如果我想以自定义错误处理方式包装它们。 -
完全正确:
StreamTransformer更强大,但实际上Stream.map已经足够好了(实际上map()、expand()和其他一些Stream方法可以使用自定义@ 来实现987654350@,但它们作为便利方法存在) -
是的,您是对的,文档确实如此。我将尝试使用
StreamTransformer,看看是否可以实现我正在寻找的自定义错误处理方式。说实话,我有一个Result类,它就像一个 Kotlin 密封类,它要么成功要么失败(借自SealedUnions包)。每次触发偶数时,如果一切正常,我想将其包装在Result.Success中,否则生成一个Result.Failure,其中包含有关问题的更多详细信息(错误消息和代码+堆栈跟踪)。 -
StreamTransformer.fromHandlers是你的朋友
标签: flutter dart async-await stream