Flutter Web (Beta), Dart, Не удается получить функцию асинхронного будущего до конца sh - с помощью JSON плагина оболочки Firestore - asy c, await, Future - PullRequest
0 голосов
/ 17 февраля 2020

Я пишу веб-приложение с Flutter (веб-сайт Flutter доступен на бета-канале), и официальная, поддерживаемая Google, библиотека Firebase не поддерживает веб-версию flutter.

Я использую плагин с открытым исходным кодом (что было невероятно), выступающий в качестве оболочки для функциональности конечной точки JSON Firebase. Плагин: https://pub.dev/packages/firebase

Future<List<Item>> pullItems(int zip, String key, int index) async {
    List<Item> itemList = [];
    final ref = store.collection("vendors-global").doc("usa").collection(zip.toString()).doc(key).collection("items");
    int i = 0;
    ref.onSnapshot.listen((querySnapshot) {
      final int snapSize = querySnapshot.size;
    querySnapshot.forEach((field) {
      var item = field.data();
      print(key + " : " + field.id);     //this prints all the items in ea. key, for debugg
      Item itemObject = new Item(item['name']);
      itemList.add(itemObject);
      i++;
      if (i == snapSize) { //this counter is how I triggered this function off after a
                     //similar function before it finished, where the parent keys came from.
        return itemList;
      }
      });
    });
  return itemList;
}

Кажется, проблема связана с .onSnapshot.listen ((querySnapshot), в частности, .listen , который является открытым Я видел, как это было сделано, когда список Предметов определен в однострочном обращении к Firestore, начиная с оператора await и заканчивая .map (() ..). toList () Но это было со стандартным API Google, который, кажется, обладает большей гибкостью.

Future<List<Item>> loadItems() async {
      final List<Item> itemList = (await Firestore.instance.collection('items').getDocuments()).documents.map((snapshot) => Item(doc['kode'], doc['name'])).toList();
      return itemList;
    }

Практическая проблема заключается в том, что эта будущая функция немедленно возвращает пустой список ItemList = [], из-за возврата в bottom. Однако, если я уберу возврат снизу, он выдаст предупреждение и не будет вычислять в этой точке.

Есть ли способ использовать функцию прослушивания .onSnapshot для обхода ряда документов в коллекции и вернуть их в виде списка?

Большое спасибо за любой вклад, это расстраивает меня в течение 10+ часов

1 Ответ

0 голосов
/ 17 февраля 2020

То, что вам нужно, это использовать Completer ... Это работает так же, как обещание отмены в javascript, если вы знакомы с этим. Проверьте это:

Future<List<Item>> pullItems(int zip, String key, int index) {
    Completer<List<Item>> completer = Completer();
    List<Item> itemList = [];
    final ref = store.collection("vendors-global").doc("usa").collection(zip.toString()).doc(key).collection("items");
    int i = 0;
    ref.onSnapshot.listen((querySnapshot) {
      final int snapSize = querySnapshot.size;
    querySnapshot.forEach((field) {
      var item = field.data();
      print(key + " : " + field.id);     //this prints all the items in ea. key, for debugg
      Item itemObject = new Item(item['name']);
      itemList.add(itemObject);
      i++;
      if (i == snapSize) { //this counter is how I triggered this function off after a
                     //similar function before it finished, where the parent keys came from.
        completer.complete(itemList);
      }
      });
    });
  return completer.future;
}

Обратите внимание, как я удалил async из конца вашей функции. async существует для автоматического создания Future<List<Item>> для вас, если есть какие-либо await вызовы, используемые внутри функции. Поскольку вы используете обратные вызовы вместо await, вам нужно просто использовать Completer, чтобы определить свое будущее для вас. Он возвращает будущее и запускает любой код, ожидающий своего «завершения», когда вызывается completer.complete(...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...