当前位置: 首页 > 知识库问答 >
问题:

whenComplete()方法未按预期工作-颤振异步

向俊贤
2023-03-14

在我的flatter应用程序中,我试图在异步函数完成后使用whenComplete()方法运行一些代码。问题是whenComplete()方法中的代码甚至在异步函数完成之前就被执行了。

我也尝试过使用then()方法,这也产生了相同的结果。

这是我在其中调用异步函数的init函数:

@override
  void initState() {
    super.initState();

    FirebaseAuth.instance.currentUser().then((user) {
      setState(() {
        mUid = user.uid;

        getUserName();
        getUserHomes().whenComplete(() {
          print(mUserHomes);
          setState(() {
            dropdownVal = mUserHomes[0];
          });
        });
      });
    }).catchError((e) {
      print(e);
    });
  }

这是异步函数的函数体:

Future getUserHomes() async {
    CollectionReference ref = Firestore.instance
        .collection('users')
        .document(mUid)
        .collection('accessibleHomes');
    QuerySnapshot eventsQuery = await ref.getDocuments();

    eventsQuery.documents.forEach((document) {
      DocumentReference homeReference = document["homeReference"];

      getHomeDevices("home", homeReference).whenComplete(() {
        setState(() {});
      });

      homeReference.get().then((DocumentSnapshot ds) {
        mUserHomes.add(ds["alias"].toString());
      });
    });
  }

运行应用程序时的控制台输出为:

Performing hot restart...
Syncing files to device ASUS Z01RD...
Restarted application in 2,521ms.
I/flutter ( 5718): []
E/flutter ( 5718): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0
E/flutter ( 5718): #0      List.[] (dart:core-patch/growable_array.dart:145:60)
E/flutter ( 5718): #1      _TabOneState.initState.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:smart_switch/home/tabs/tab_one/tab_one_content.dart:52:37)
E/flutter ( 5718): #2      State.setState (package:flutter/src/widgets/framework.dart:1117:30)
E/flutter ( 5718): #3      _TabOneState.initState.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:smart_switch/home/tabs/tab_one/tab_one_content.dart:51:11)
E/flutter ( 5718): #4      _rootRun (dart:async/zone.dart:1120:38)
E/flutter ( 5718): #5      _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 5718): #6      _FutureListener.handleWhenComplete (dart:async/future_impl.dart:150:18)
E/flutter ( 5718): #7      Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:609:39)
E/flutter ( 5718): #8      Future._propagateToListeners (dart:async/future_impl.dart:665:37)
E/flutter ( 5718): #9      Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 5718): #10     _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 5718): #11     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 5718): #12     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 5718): #13     _TabOneState.getUserHomes (package:smart_switch/home/tabs/tab_one/tab_one_content.dart)
E/flutter ( 5718): #14     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 5718): #15     _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 5718): #16     _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 5718): #17     _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 5718): #18     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 5718): #19     Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 5718): #20     Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 5718): #21     _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 5718): #22     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 5718): #23     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 5718): #24     Query.getDocuments (package:cloud_firestore/src/query.dart)
E/flutter ( 5718): #25     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 5718): #26     _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 5718): #27     _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 5718): #28     _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 5718): #29     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 5718): #30     Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 5718): #31     Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 5718): #32     _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 5718): #33     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 5718): #34     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 5718): #35     MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart)
E/flutter ( 5718): #36     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 5718): #37     _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 5718): #38     _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 5718): #39     _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 5718): #40     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 5718): #41     Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 5718): #42     Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 5718): #43     _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 5718): #44     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 5718): #45     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 5718): #46     MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart)
E/flutter ( 5718): #47     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 5718): #48     _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 5718): #49     _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 5718): #50     _FutureListener.handleValue (dart:async/future_impl.dart:126


因此,在调用异步函数getUserHomes的init()函数中,我试图将dropdownVal变量设置为从Firestore DB获取的列表mUserHomes的第一个值。该列表在控制台中打印为[],这意味着为空,但如果我在稍后阶段打印该列表,则会打印出值。

共有2个答案

栾和玉
2023-03-14

我也遇到了同样的问题,并且意识到如果使用for循环,那么不用foreach方法,事情就会按预期工作

苏华荣
2023-03-14

您的getUserHomes函数在它不等待的foreach回调中执行大量异步工作,因此getUserHomes几乎在ref.getDocuments完成后立即完成其返回的Future

如果要等待getUserHomes中的所有工作完成,可以执行以下操作:

Future<void> getUserHomes() async {
  CollectionReference ref = Firestore.instance
      .collection('users')
      .document(mUid)
      .collection('accessibleHomes');
  QuerySnapshot eventsQuery = await ref.getDocuments();

  final waitList = <Future<void>>[];

  for (var document in eventsQuery.documents) {
    DocumentReference homeReference = document["homeReference"];

    waitList.add(getHomeDevices("home", homeReference));
    waitList.add(
      homeReference.get().then((DocumentSnapshot ds) {
        mUserHomes.add(ds["alias"].toString());
      });
    );
  }

  await Future.wait(waitList);
}
 类似资料:
  • 自从我开始使用Flatter以来,我面临着一个与Flatter async await相关的问题。大多数时候,我试图用未来和等待的结果,它跳过等待,并得到最短的方式返回 请帮助我更好地理解flatter async wait,或者告诉我哪里做错了,这样我就可以改进我的代码

  • 根据以下文档:http://testng.org/doc/documentation-main.html “如果测试类上有一个方法tearDown(),那么在每个测试方法之前和之后都会调用它”(JUnit 3) 我使用的是JUnit版本:3.8.1 这里的这个是在我的测试之前运行的,但我希望它会在测试之后。它在测试后没有运行: 我可以通过将第一行更改为: 但是,下一个类(下面)的表示法与第一个类完

  • 问题内容: 建立: 我正在做一个ajax-jsonp调用,它工作正常。此的回调函数更改变量“ myVaraible”的值。在调用之后,有一些if-else逻辑对“ myVaraible”的值起作用。 这是代码: 问题: Ajax调用保持“待处理”状态,控制移至if- else块(有效执行myVariable的旧/陈旧值)。然后,ajax调用完成。简而言之,在两个方框中,先执行然后执行 如您所见,我

  • 我正在使用spring Roo并希望访问Controller类中的一个bean,该类在ApplicationContext.xml中具有以下配置: 配置类本身是: 在我的Controller中,我认为一个简单的Autowired注释应该可以完成这项工作 在启动过程中,spring在setSkipWeeks方法中打印消息。不幸的是,每当我在控制器中调用config.getSkipWeeks()时,它

  • 当我运行以下程序时,它只打印 然而,从Java 8的equalsIgnoreCase文档中我们发现: 如果以下至少一项为真,则两个字符c1和c2被视为相同的忽略情况: •对每个字符应用java.lang.character.ToUpperCase(char)方法会产生相同的结果 所以我的问题是为什么这个程序不打印 在这两种操作中,都使用了大写字符。

  • 我试图使用来传输我根据前面的问题设置的自定义标头。 我在文件中读到... 我的属性包括: