【问题标题】:Future ignores await in flutter未来忽略等待
【发布时间】:2021-03-26 07:22:02
【问题描述】:

我正在尝试为我的应用程序进行版本控制。换句话说,尝试连接到 firebase 文档,从那里选择版本号并将其与共享首选项中的值进行比较,以确定是否需要更新信息。

我已按照 Futures 的官方教程进行操作。

这是我的代码:

@override
  void initState(){
    loadit();
  }

Future _getIntVersionFromSharedPref() async {
    await Firestore.instance.collection('DataIndex')
        .document('dbversion').snapshots().listen((event) {
      setState(() {
        fbVersion = event['currentversion'];
      });
      print('_getIntVersionFromSharedPref() future -> $fbVersion');
      return fbVersion;
    });
  }

  Future<String> loadit() async {
    var myFBversion = await _getIntVersionFromSharedPref();
    print('loadit future -> $myFBversion');
  }

但是我最终得到以下控制台输出:

I/flutter: loadit future -> null
I/flutter: _getIntVersionFromSharedPref() future -> 1

为什么它会在不等待值的情况下立即触发 null?按照官方教程应该是依次执行的。

【问题讨论】:

  • 我不确定firebase,因为我从未使用过它,但我认为你正在等待然后。您应该只使用两者之一。如果你使用 await 你应该创建一个值,或者如果你使用 then 你不需要做 await (我认为 listen 和 then 一样)。
  • @AyadRocketfy OP 的代码中没有 then 的实例。
  • 老实说,我不确定 OP 的代码是如何编译的。有一种方法返回 Future&lt;String&gt; 但没有返回语句,他们正在等待一些不是未来的东西。

标签: firebase flutter dart google-cloud-firestore future


【解决方案1】:

listen() 不返回 Future,所以你不能等待它。它异步返回一个 StreamSubscription 对象,您必须在流处理函数中处理查询的持续结果。完成流后,您应该使用 StreamSubscription 取消订阅流。

如果您只想要文档的单个快照,则根本不要使用snapshots()。只需使用get() 获取单个快照,如documentation 所示。

【讨论】:

    【解决方案2】:

    Listen 不是 dart Future API 的一部分,因此 listen 回调不会绑定到从 _getIntVersionFromSharedPref 隐式返回的 Promise。

    我认为您需要从该方法手动返回一个 Promise,并从您的侦听回调中解决它。您可以像这样使用Completer 类手动解析Future

    类似这样的:

    Future _getIntVersionFromSharedPref() async {
      var completer = Completer<num>();
      await Firestore.instance.collection('DataIndex')
          .document('dbversion').snapshots().listen((event) {
        setState(() {
          fbVersion = event['currentversion'];
        });
        print('_getIntVersionFromSharedPref() future -> $fbVersion');
        completer.complete($fbVersion);
      });
    
      // This will be returned right away, but anything that awaits it will block
      // until the callback above has completed the future.
      return completer.future;
    }
    

    【讨论】:

    • 这可能有效,但是当您可以像 Doug 的回答所建议的那样获得单个快照时,使用完成器是没有用的。
    猜你喜欢
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多