我正在查询 Firestore 并将 Stream 作为 QuerySnapshots Stream 取回。我需要将流中包含的文档映射到对象列表。
下面的代码不起作用(显然)......也许我只是在看这完全错误。
List<UserTask> getUserTaskList() {
List<UserTask> list;
Stream<QuerySnapshot> stream =
Firestore.instance.collection('userTasks').snapshots();
stream.listen((snapshot) {
snapshot.documents.forEach((doc) {
UserTask userTask = UserTask(
doc.data['id'],
doc.data['Description'],
etc...);
list.add(userTask);
});
});
return list;
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,由于它不等待整个流(或实际中的任何一个),因此 list 始终返回为 null。简而言之,如何将我的流转换为列表?
注意:我对 Dart 的世界还很陌生,所以对我放轻松 :)
谢谢!
Gaz*_*kus 21
首先,想一想:这个函数必须非常快地返回。所有功能都可以,否则 UI 会挂起。但是,您希望该函数返回来自 Internet 的内容。这需要时间。该函数必须返回。函数无法简单地执行网络请求并返回结果。欢迎来到异步编程的世界。
此外,您拥有的流不是DocumentSnapshots流(您可以将其转换为UserTasks),而是QuerySnapshots流(您可以将其转换为List<UserTask>s)。注意那里的复数。如果您只是想UserTask一次性获得所有s,则应该使用 aFuture而不是 a Stream。如果您想UserTask在每次更改后重复获取所有s,那么使用 aStream是有意义的。
既然你说你想得到 a List<UserTask>,我假设你只想得到UserTasks的集合一次。
这就是你的代码在这种情况下变成的:
Future<List<UserTask>> getUserTaskList() async {
QuerySnapshot qShot =
await Firestore.instance.collection('userTasks').getDocuments();
return qShot.documents.map(
(doc) => UserTask(
doc.data['id'],
doc.data['Description'],
etc...)
).toList();
}
main() async {
List<UserTask> tasks = await getUserTaskList();
useTasklist(tasks); // yay, the list is here
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你真的想使用流,你可以这样做:
Stream<List<UserTask>> getUserTaskLists() async {
Stream<QuerySnapshot> stream =
Firestore.instance.collection('userTasks').snapshots();
return stream.map(
(qShot) => qShot.documents.map(
(doc) => UserTask(
doc.data['id'],
doc.data['Description'],
etc...)
).toList()
);
}
main() async {
await for (List<UserTask> tasks in getUserTaskLists()) {
useTasklist(tasks); // yay, the NEXT list is here
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你。