Flutter Web(测试版),Dart,无法完成异步未来函数 - 使用JSON Firestore包装器插件 - asyc,等待,未来



我正在用Flutter编写一个网络应用程序(Flutter网络在测试版频道上可用(,而官方的、谷歌支持的Firebase库不支持网络版本的Flutter。

我使用的是一个开源插件(非常棒(,作为Firebase的JSON端点功能的包装器。插件: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.restant((querySnapshot(,特别是.restant,是一个开放连接。我看到过这样做,即在对Firestore的单行调用中定义项列表,从wait语句开始,到.map(((..(.toList((结束。但它是使用标准的googleneneneba API的,它似乎有更大的灵活性。

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;
}

实际问题是,这个未来函数会立即返回空白的List itemList=[];由于底部的回流。然而,如果我删除底部返回,它会抛出一个警告,并且此时不会进行计算。

有没有任何方法可以使用.onSnapshot侦听功能遍历集合中的多个文档,并将它们作为列表返回?

非常感谢您的任何输入,这已经让我沮丧了10多个小时

您需要的是使用Completer。。。如果您熟悉的话,这就像javascript中的promise defial一样工作。看看:

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的。。如果函数内部使用了await调用,async会自动为您创建Future<List<Item>>。既然您使用的是回调而不是await,那么您应该只使用Completer来处理您的未来。它返回future,并将在调用completer.complete(...)时触发任何等待其"完成"的代码。

最新更新