颤振和块异步产量
Posted
技术标签:
【中文标题】颤振和块异步产量【英文标题】:flutter and bloc asynchronous yield 【发布时间】:2020-06-18 19:45:14 【问题描述】:我正在使用带有 BLoC 模式的颤振(使用 flutter_bloc 库)并且我有这些事件:
PersonalFileAddedEvent(File file), PersonalFileUploadEvent(PersonalFile file)
(都从PersonalFileEvent
扩展而来)
File 是来自文件选择器的文件,PersonalFile 是具有以下枚举状态的类:READY_TO_UPLOAD, UPLOADING, UPLOAD_FINISHED
。
以及来自 BLoC 的这个状态:
PersonalFileListLoadedState(List<PersonalFile> files)
(从PersonalFileListState
扩展)
当用户选择一个文件时,UI 调用事件 PersonalFileAddedEvent
并将其传递给 BLoC,该 BLoC 创建一个 PersonalFile
对象并将其状态设置为 READY_TO_UPLOAD
。这个PersonalFile
对象得到
添加到包含用户正在添加(和上传)的所有 PersonalFile 的列表中。然后 BLoC 使用 PersonalFileListLoadedState(blocPersonalFileList)
向 UI 响应 (yield
) 以呈现信息。
添加后,会在 UI 中为 PersonalFile
呈现一个“立即上传”按钮。按下时,它会调用PersonalFileUploadEvent
事件并将PersonalFile
发送到 BLoC 以启动上传过程(分段上传)。
收到事件后,BLoC 立即将此 PersonalFile 的状态更新为 UPLOADING
和 yield
PersonalFileListLoadedState
状态,同时更新 PersonalFile 的状态以供 UI 显示它正在上传。
上传multipart文件的方法是async:
Future<PersonalFile> upload(PersonalFile file) async //upload code
这是来自 flutter_bloc 的 mapEventToState:
Stream<PersonalFileListState> mapEventToState(PersonalFileEvent event) async*
在这个 mapEventToState
方法中,我正在等待上传方法将 PersonalFile 的状态更新为 UPLOAD_FINISHED
。
问题从现在开始,因为用户从文件选择器中添加了几个文件,并按下了所有“上传”按钮。 BLoC 在接收到第一个事件后被阻塞并处理“类似同步”的事件和 UI 就好像在第一个完成(然后是下一个,依此类推)之前没有按下另一个 PersonalFile 的“上传”按钮。
在一个事件被完全处理(上传完成)后,下一个事件被处理,这是有道理的,因为我正在等待上传方法完成。
如何编写此代码,以便如果用户在 UI 中按下多个“上传”按钮,BLoC 不会被阻止(因此 UI 因为 BLoC 无法yield
新状态)和所有文件被上传
并行,但仅在每个人完成之前,BLoC 发送 PersonalFile
的新 List
并将其状态更改为 UPLOAD_FINISHED
?
我已尝试将上传方法的签名更改为:
Stream<PersonalFile> upload(PersonalFile file) async* //upload code
并使用:
.then((file) yield PersonalFileListLoadedState(listWithUpdatedPersonalFileStatus) )
但是里面的代码永远不会被执行。我尝试调试,但无法到达断点。
【问题讨论】:
【参考方案1】:不确定您是如何调用 bloc 来启动进程上传的。
但是,如果您在按下按钮时使用bloc.add(event)
,则应该以异步方式对其进行处理,并根据需要产生新的状态。
另外请注意,当您处理状态更改时,如果多次产生相同的状态,侦听器只会侦听一次,因此您不会在 UI 中看到多个更新。
希望这会有所帮助。
【讨论】:
没错,在集团内部添加新事件非常有用。非常感谢! @HollandSalazar 你是如何在 bloc 中添加事件的?你能帮我写一些代码吗? 例如,当您按下按钮时,您将该事件添加为bloc.add(my_event)
,因此在您的块中,在处理事件的方法中您可以执行以下操作:Stream<PrintJobsState> _addPrintJob(PrintJob job, StorageProvider provider, StorageFile file) async* /// process your event. add(new_event); /// Continue processing your event
以上是关于颤振和块异步产量的主要内容,如果未能解决你的问题,请参考以下文章