Flutter 如何在Dart中使用async*函数

Flutter 如何在Dart中使用async*函数,flutter,dart,dart-async,Flutter,Dart,Dart Async,我正在使用Flatter_bloc库 在bloc中,mapEventToState方法是一个async*函数,它返回Stream。 从这个函数中,我调用了其他的async*函数,比如yield*\u handleEvent(event) 在这种方法中,我调用一些Future returns函数,但在Futurethen()函数中,它不允许我调用其他yield*函数 以下是一个例子: Stream<BlocState> mapEventToState(BlocEvent event)

我正在使用Flatter_bloc库

在bloc中,
mapEventToState
方法是一个
async*
函数,它返回
Stream
。 从这个函数中,我调用了其他的
async*
函数,比如
yield*\u handleEvent(event)

在这种方法中,我调用一些Future returns函数,但在Future
then()
函数中,它不允许我调用其他yield*函数

以下是一个例子:

Stream<BlocState> mapEventToState(BlocEvent event) async*{
     yield* _handlesEvent(event); //This calls to worker method 
}

Stream<BlocState> _handleEvent(BlocEvent event) async* {
   _repository.getData(event.id).then((response) async* { //Calling Future returned function
         yield* _processResult(response); //This won't work
     }).catchError((e)  async* {
         yield* _handleError(e);  //This won't work either
     });

   Response response = await _repository.getData(event.id); //This do works but I want to use it like above, is it possible?
   yield* _processResult(response); //This do works
}
流mapEventToState(BloceEvent事件)异步*{
yield*\u handlesEvent(event);//此函数调用worker方法
}
Stream\u handleEvent(BloceEvent事件)异步*{
_getData(event.id).then((response)async*{//调用Future返回的函数
yield*\u processResult(response);//这不起作用
}).catchError((e)异步*{
yield*_handleError(e);//这也行不通
});
Response Response=await _repository.getData(event.id);//这确实有效,但我想像上面那样使用它,可能吗?
yield*_processResult(response);//这确实有效
}
然而,问题是,如何在dart中将未来和流结合起来。
我可以使用
await\u repository.getData
,它可以工作。但是我不会捕捉错误。

尝试使用
Try catch
块。它适用于我的等待操作

  • await
    只是
    的语法糖。然后()
    ,将
    await
    放入
    try
    -
    catch
    块是使用
    .catchError
    的语法糖。你可以用一种方法做的事情可以用另一种方法做

  • 在使用
    .then()
    /
    .catchError()
    的第一个版本中,函数不会返回任何内容

  • 您的回调不起作用,因为您在回调中使用了
    yield*
    ,但您没有使用
    sync*
    async*
    指定回调。为了避免名称冲突,
    yield
    关键字需要它们(与
    await
    需要函数use
    async
    async*
    的方式相同)

  • 下面是一个应该与
    .then()
    .catchError()一起使用的版本:

    Stream\u handleEvent(BloceEvent事件)异步*{
    yield*await\u repository.getData(event.id).then((response)async*{
    产量*\u处理结果(响应);
    }).catchError((e)异步*{
    收益率*_handleError(e);
    });
    }
    
    注意回调不需要使用
    yield*
    ;他们可以直接返回
    s:

    Stream\u handleEvent(BloceEvent事件)异步*{
    yield*await\u repository.getData(event.id).then((响应){
    返回processResult(响应);
    }).catchError((e){
    返回_handleError(e);
    });
    }
    
    但是(正如大家所注意到的)使用
    await
    而不是
    Future
    API简化了整个过程(特别是因为我们已经在使用
    await
    ):

    Stream\u handleEvent(BloceEvent事件)异步*{
    尝试
    response=wait_repository.getData(event.id);
    产量*\u处理结果(响应);
    }捕获(e){
    收益率*_handleError(e);
    }
    }
    

    有关可运行的示例,请参阅。

    要处理异步函数中的错误,请使用try-catch:

    try {
      Response response = await _repository.getData(event.id)
    } catch (err) {
      print('Caught error: $err');
    }
    

    使用简单的
    await
    代替
    then
    var response=await\u repository.getData(event.id);产量*\u处理结果(响应)谢谢,我在问题中提到了这一点,我如何捕捉这样的错误?我想使用未来api的内置捕获错误。使用普通的try-catch-什么不起作用?谢谢,请参考我对@Candace belowThanks的回复,我考虑过这个问题,但未来api已经有捕获错误api,我只是想知道我是否可以使用它。这就像用另一次尝试来包装-catch@MotiBartov它没有包装任何东西。Dart编译器将自动将
    try{wait future;}catch{…}
    转换为适当的
    future.then().catchError()
    构造。这是语法上的糖。当然,多谢了,_processResult和_handleError是最终产生蒸汽最终状态的发生器。收益率在回调中也不起作用,因为它们是闭包。@MotiBartov我不理解你所说的“收益率在回调中也不起作用,因为它们是闭包”。我是说您需要将
    (response){yield*…}
    更改为
    (response)async*{yield*…}
    。我已经尝试过了,它不起作用。(respose){}实际上是一个内部对象否?它的作用域不允许屈服*或屈服于外部类函数流
    (response){…}
    构造匿名函数。您完全可以将
    async、
    async*、
    sync*
    添加到匿名函数中。通常您是正确的,但请记住这些外部函数返回流,匿名函数返回类型未定义,因此即使我将其设置为async*它也不是同一个流。当我尝试这个的时候,它不起作用。