代码之家  ›  专栏  ›  技术社区  ›  Maurits van Beusekom

有没有办法避免等待异步方法返回流?

  •  2
  • Maurits van Beusekom  · 技术社区  · 6 年前

    我们现在有一个方法返回 Future<Stream<Position>> 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;
    }
    

    1. 我们在等待 _getLocationPermission() 方法,以便我们可以测试用户是否授予我们访问其设备(Android或iOS)上的位置服务的权限;
    2. 如果用户授予我们权限,我们将返回 流<位置> 它将在设备每次注册位置更改时更新。

    未来 . 大致如下:

    1. 手动创建并返回 流<位置>
    2. 处理检查权限和调用 _eventChannel.receiveBroadcastStream then() 方法 Future<PermissionStatus> _getLocationPermission()
    3. 从中复制流上发送的事件 _eventChannel.receiveBroadcastStream事件频道.receiveBroadcastStream 到先前创建(和返回)的流中。

    _eventChannel 等。

    所以我想问题是,什么是处理这种情况的最佳方法?

    1 回复  |  直到 6 年前
        1
  •  5
  •   lrn    6 年前

    你可以把代码写成 async* 函数,它将返回 Stream 仍然允许 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 package:async 它允许您返回 溪流 河流完成器