列表未通过异步方法更新

List not getting updated through async method

这是我的代码:

List<String> databaseEntryID = <String>[];

readAllData() async {
    await db.collection("users").get().then((event) {
      for (var doc in event.docs) {
        print(doc.id);
        databaseEntryID.add(doc.id);
      }
    });
  }

  readData() {
    final docRef = db.collection(databaseEntryID[0]).doc(databaseEntryID[1]);
    docRef.get().then(
          (res) => print("Successfully completed"),
      onError: (e) => print("Error completing: $e"),
    );
  }

如果我先调用 readAllData() 然后再调用 readData(),我会得到一个 RangeError:RangeError (index): Invalid value: Valid value range is empty: 0.

我没有完全理解异步是如何工作的,所以我在这里做错了什么,我如何先更新列表,然后访问第一个和第二个字符串?

对于Async,我一般会实现Listener Pattern。这样,当您从异步接收数据时,您可以使用它。基本上,这里发生的是您在 readAllData() 结果到达之前无法使用 readData()。你可以 do/try 做些什么来修补这个: 1.


readAllData() async {
    await db.collection("users").get().then((event) {
      for (var doc in event.docs) {
        print(doc.id);
        databaseEntryID.add(doc.id);
      }
      // Do here the things you might want to do when receiving an information (such as notifying the listeners..)
    });
  }

或 2.

List<String> databaseEntryID = <String>[];
Boolean databaseHydrated = false;

readAllData() async {
    await db.collection("users").get().then((event) {
      for (var doc in event.docs) {
        print(doc.id);
        databaseEntryID.add(doc.id);
      }
      databaseHydrated = true;
    });
  }

  readData() {
    if(databaseHydrated) {
      final docRef = db.collection(databaseEntryID[0]).doc(databaseEntryID[1]);
      docRef.get().then(
            (res) => print("Successfully completed"),
        onError: (e) => print("Error completing: $e"),
      );
    } else {
      // Do whatever you want, like toggle a loading screen while waiting for async data ?
    }
  }

希望对您有所帮助!

我在搜索后发现了这个,应该先检查一下(我通常避免使用文档页面,因为它们太复杂了,比如这个是指南):https://dart.dev/codelabs/async-await

所以最简单的解决方法是:

List<String> databaseEntryID = <String>[];

readAllData() async {
    await db.collection("users").get().then((event) {
      for (var doc in event.docs) {
        print(doc.id);
        databaseEntryID.add(doc.id);
      }
    });
  }

  readData() async {
    await readAllData();

    final docRef = db.collection(databaseEntryID[0]).doc(databaseEntryID[1]);
    docRef.get().then(
          (res) => print("Successfully completed"),
      onError: (e) => print("Error completing: $e"),
    );
  }

使用await关键字从readData调用readAllData函数,表明它需要等待它的return,然后执行 readData 方法(需要 async 修饰符)。