我遇到了一个奇怪的问题,即如果我在flutter应用程序中从提供程序中获取*,该函数中的其余代码将无法完成。
我正在使用BLoC模式,因此我的_mapEventToState函数如下所示:
Stream<WizardState> _mapJoiningCongregationToState(
int identifier, int password) async* {
_subscription?.cancel();
_subscription= (_provider.doThings(
id: identifier, password: password))
.listen((progress) => {
dispatch(Event(
progressMessage: progress.progressText))
}, onError: (error){
print(error);
}, onDone: (){
print('done joiining');
});
}
然后在提供者/服务中...这是第一次尝试。
final StreamController<Progress> _progressStream = StreamController<JoinCongregationProgress>();
@override
Stream<JoinCongregationProgress> doThings(
{int id, int password}) async* {
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake1..."));
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake5!!!..."));
yield* _progressStream.stream;
}
yield语句返回,但是仅在 之后两个函数都已完成。这对我来说是完全有意义的,显然,我不希望代码在等待“等待”完成之前会乱序完成,并以某种方式运行yield *。
不过,为了“订阅”该服务的进度,我需要将流交还给调用者,在UI上编写更新等。在我看来,这就像移动产量一样简单*到第一次等待之前。这样。
final StreamController<Progress> _progressStream = StreamController<JoinCongregationProgress>();
@override
Stream<JoinCongregationProgress> doThings(
{int id, int password}) async* {
yield* _progressStream.stream;
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake1..."));
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake5!!!..."));
}
但是,然后在以后的_progressStream.add调用中设置断点表明这些断点永远不会被调用。我一直坚持下去,知道这可能是什么吗?我知道这与我如何混合期货和股流有关。
答案 0 :(得分:1)
yield*
等待返回的流完成。
在这种情况下,您想立即返回一个流,然后将一些数据异步馈入该流。
其他是否有向事件流控制器添加事件的东西?如果没有,您应该能够做到:
@override
Stream<JoinCongregationProgress> doThings({int id, int password}) async* {
await Future.delayed(Duration(seconds:2));
yield JoinCongregationProgress(progressText: "kake1...");
await Future.delayed(Duration(seconds:2));
yield JoinCongregationProgress(progressText: "kake5!!!...");
}
不需要流控制器。
如果其他功能也添加到流控制器中,那么您确实需要它。然后,您必须将流创建分散到一个异步部分(该部分更新流控制器)和一个同步部分(返回流)中。也许:
final StreamController<Progress> _progressStream = StreamController<JoinCongregationProgress>();
@override
Stream<JoinCongregationProgress> doThings({int id, int password}) {
() async {
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake1..."));
await Future.delayed(Duration(seconds:2));
_progressStream.add(JoinCongregationProgress(progressText: "kake5!!!..."));
}(); // Spin off async background task to update stream controller.
return _progressStream.stream;
}