asynchronous - 有没有办法防止必须等待返回流的异步方法?
问题描述
我们目前有一个返回 a 的方法,Future<Stream<Position>>
因为在内部我们必须等待返回 a 的方法的结果,Future
然后才能调用另一个返回Stream<Position>
我们真正感兴趣的方法。下面是代码:
Future<Stream<Position>> getPositionStream(
[LocationOptions locationOptions = const LocationOptions()]) async {
PermissionStatus permission = await _getLocationPermission();
if (permission == PermissionStatus.granted) {
if (_onPositionChanged == null) {
_onPositionChanged = _eventChannel
.receiveBroadcastStream(
Codec.encodeLocationOptions(locationOptions))
.map<Position>(
(element) => Position._fromMap(element.cast<String, double>()));
}
return _onPositionChanged;
} else {
_handleInvalidPermissions(permission);
}
return null;
}
所以这里发生的是:
- 我们等待该
_getLocationPermission()
方法,以便我们可以测试用户是否授予我们访问其设备(Android 或 iOS)上位置服务的权限; - 如果用户授予我们权限,我们将返回一个
Stream<Position>
将在每次设备注册位置更改时更新。
我觉得我们也可以在不执行 await 并返回Future
. 类似于以下内容:
- 手动创建并返回
Stream<Position>
该类的实例; - 处理从方法返回的
_eventChannel.receiveBroadcastStream
方法then()
中检查权限和调用的逻辑(所以我们不必等待它);Future<PermissionStatus>
_getLocationPermission()
- 将流上发送的事件从
_eventChannel.receiveBroadcastStream
复制到先前创建(并返回)的流上。
不知何故,这似乎是可能的,但也包括管理流的一些开销,并确保它在插件的实时周期期间关闭并正确清理,或者当用户取消订阅时将事件传递给_eventChannel
等。
所以我想问题是,处理这种情况的最佳方法是什么?
解决方案
您可以将代码编写为async*
函数,该函数将返回 aStream
并且仍然允许await
在正文中:
Stream<Position> getPositionStream(
[LocationOptions locationOptions = const LocationOptions()]) async* {
PermissionStatus permission = await _getLocationPermission();
if (permission == PermissionStatus.granted) {
if (_onPositionChanged == null) {
_onPositionChanged = _eventChannel
.receiveBroadcastStream(
Codec.encodeLocationOptions(locationOptions))
.map<Position>(
(element) => Position._fromMap(element.cast<String, double>()));
}
yield* _onPositionChanged;
} else {
_handleInvalidPermissions(permission);
}
}
或者,如果您使用的是非async
函数,您也可以使用StreamCompleter
from package:async
。它允许您现在返回Stream
,即使您稍后才获得真正的流。当这种情况发生时,你StreamCompleter
用真实的流“完成”,原始流的行为就好像它是真实的流一样。
推荐阅读
- android - Android:单击按钮时如何显示光标
- arrays - Angular 8错误“错误错误:“找不到名称为'getAccountArr'的控件”“使用表单数组时
- python - 列上的 Multiindiex str 替换
- python - Python中的生日悖论与蒙特卡罗方法?
- ios - Objective-C - 当 iOS 13 暗模式更改时,以编程方式更改渐变背景颜色 UIViewController
- python-3.x - 如何在单个部分中运行 jupyter notebook 代码?
- powerbi - 在 Power BI DAX 中应用任何筛选器时总价值发生变化
- r - 使用来自另一个数据帧的 id 和时间戳创建特定的输出
- linux - 为什么在没有安装 devtmpfs 并记录时,我会从 ACPID 获得控制台输出?
- c# - 如何将自定义符号添加到正则表达式?DevExpress 掩码