[英]Dart yield stream events from another stream listener
我有一个生成特定事件stream
的函数。 现在我有一个来自存储服务的流,它有自己的事件。 寻找一种在storage stream
发生变化时产生我的事件的方法。
此代码片段不起作用。
Stream<BlocState> mapEventToState(
BlocEvent event,
) async* {
if (event is UploadData) {
yield UploadDataProgress(progress: 0.0);
final Storage storage = Storage();
final Stream<StorageEvent> upload = storage.upload(event.data);
upload.listen((StorageEvent storageEvent) async* {
print('***** Listener: ${storageEvent.type} - ${storageEvent.progress}');
if (storageEvent.type == StorageEventType.error) {
yield UploadDataError(errorMessage: storageEvent.error);
}
if (storageEvent.type == StorageEventType.success) {
yield UploadDataSuccess();
}
if (storageEvent.type == StorageEventType.progress) {
yield UploadDataProgress(progress: storageEvent.progress);
}
});
}
}
输出:调试打印有效,但事件未发送到侦听器。
***** Listener: StorageEventType.progress - 0.01924033836457124
***** Listener: StorageEventType.progress - 0.044581091468101464
***** Listener: StorageEventType.progress - 0.6986233206170177
***** Listener: StorageEventType.progress - 1.0
您的yield
来自匿名函数(StorageEvent storageEvent) async* {
而不是来自mapEventToState
。
简单地用await for
替换listen()
应该可以工作。
Stream<BlocState> mapEventToState(
BlocEvent event,
) async* {
if (event is UploadData) {
yield UploadDataProgress(progress: 0.0);
final Storage storage = Storage();
final Stream<StorageEvent> upload = storage.upload(event.data);
await for (StorageEvent storageEvent in upload) {
print('***** Listener: ${storageEvent.type} - ${storageEvent.progress}');
if (storageEvent.type == StorageEventType.error) {
yield UploadDataError(errorMessage: storageEvent.error);
}
if (storageEvent.type == StorageEventType.success) {
yield UploadDataSuccess();
}
if (storageEvent.type == StorageEventType.progress) {
yield UploadDataProgress(progress: storageEvent.progress);
}
}
}
}
物有所值。 我有一个类似的问题,我订阅了 Firebase 快照并尝试根据文档数据产生事件。
如果我使用 await-for 范式,我将无法获得订阅句柄。 结果,当我想关闭 BLoC 时,停止读取流变得很痛苦。
我找到了一个全面的解决方案。
Stream<BlocState> mapEventToState(BlocEvent event) async* {
if (event is FetchEvent) {
yield LoadingState();
_subscription = SomeStream(event.someKey).listen((snapshot) {
add(OnSnapshotEvent(snapshot));
});
}
if (event is OnSnapshotEvent) {
if (SomeCondition(event.snapshot)) {
yield SomeResultState();
} else {
yield SomeOtherState();
}
}
}
这样,我就有了订阅的句柄,所以我总是可以很好地清理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.