如何在 Dart 中使用 async* 函数
How to work with async* functions in Dart
我正在使用 flutter_bloc 库。
在 bloc 中,mapEventToState
方法是一个 async*
函数,returns Stream<BlocState>
。
从这个函数我调用其他 async*
函数,像这样 yield* _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
}
但是问题是,如何在dart中结合Future和Stream。
我可以使用有效的 await _repository.getData
。但是我不会发现错误。
尝试使用 try-catch
块。它适用于等待操作。
await
只是.then()
的语法糖,把await
放在try
-catch
块中是语法糖使用 .catchError
。您可以用一种方式完成的事情可以用另一种方式完成。
在您使用 .then()
/.catchError()
的第一个版本中,您的函数没有 return 任何东西。
您的回调将无法工作,因为您在其中使用了 yield*
,但您没有使用 sync*
或 async*
指定回调。为避免名称冲突,yield
关键字需要它们(就像 await
需要使用 async
或 async*
的函数一样)。
这是一个可以与 .then()
和 .catchError()
一起使用的版本:
Stream<BlocState> _handleEvent(BlocEvent event) async* {
yield* await _repository.getData(event.id).then((response) async* {
yield* _processResult(response);
}).catchError((e) async* {
yield* _handleError(e);
});
}
注意回调不需要使用yield*
;他们可以 return 他们的 Stream
直接:
Stream<BlocState> _handleEvent(BlocEvent event) async* {
yield* await _repository.getData(event.id).then((response) {
return _processResult(response);
}).catchError((e) {
return _handleError(e);
});
}
但是(正如其他人所指出的)使用 await
而不是 Future
API 简化了整个事情(特别是因为我们已经在使用 await
):
Stream<BlocState> _handleEvent(BlocEvent event) async* {
try
response = await _repository.getData(event.id);
yield* _processResult(response);
} catch (e) {
yield* _handleError(e);
}
}
有关可运行示例,请参阅 https://dartpad.dartlang.org/fc1ff92e461754bdb35b998e7fbb3406。
要处理异步函数中的错误,请使用 try-catch:
try {
Response response = await _repository.getData(event.id)
} catch (err) {
print('Caught error: $err');
}
我正在使用 flutter_bloc 库。
在 bloc 中,mapEventToState
方法是一个 async*
函数,returns Stream<BlocState>
。
从这个函数我调用其他 async*
函数,像这样 yield* _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
}
但是问题是,如何在dart中结合Future和Stream。
我可以使用有效的 await _repository.getData
。但是我不会发现错误。
尝试使用 try-catch
块。它适用于等待操作。
await
只是.then()
的语法糖,把await
放在try
-catch
块中是语法糖使用.catchError
。您可以用一种方式完成的事情可以用另一种方式完成。在您使用
.then()
/.catchError()
的第一个版本中,您的函数没有 return 任何东西。您的回调将无法工作,因为您在其中使用了
yield*
,但您没有使用sync*
或async*
指定回调。为避免名称冲突,yield
关键字需要它们(就像await
需要使用async
或async*
的函数一样)。
这是一个可以与 .then()
和 .catchError()
一起使用的版本:
Stream<BlocState> _handleEvent(BlocEvent event) async* {
yield* await _repository.getData(event.id).then((response) async* {
yield* _processResult(response);
}).catchError((e) async* {
yield* _handleError(e);
});
}
注意回调不需要使用yield*
;他们可以 return 他们的 Stream
直接:
Stream<BlocState> _handleEvent(BlocEvent event) async* {
yield* await _repository.getData(event.id).then((response) {
return _processResult(response);
}).catchError((e) {
return _handleError(e);
});
}
但是(正如其他人所指出的)使用 await
而不是 Future
API 简化了整个事情(特别是因为我们已经在使用 await
):
Stream<BlocState> _handleEvent(BlocEvent event) async* {
try
response = await _repository.getData(event.id);
yield* _processResult(response);
} catch (e) {
yield* _handleError(e);
}
}
有关可运行示例,请参阅 https://dartpad.dartlang.org/fc1ff92e461754bdb35b998e7fbb3406。
要处理异步函数中的错误,请使用 try-catch:
try {
Response response = await _repository.getData(event.id)
} catch (err) {
print('Caught error: $err');
}