我想从实时Firebase数据库中快速加载列表,然后等待加载完成。我希望
FirebaseDatabase database = new FirebaseDatabase();
Query _newsQuery = database
.reference()
.child('news')
.orderByChild('published')
.limitToFirst(10);
Future<List<News>> loadNews() async {
List<News> list = new List<News>();
_newsQuery.onChildAdded.listen(onNewsAdded);
return list;
}
Future<News> onNewsAdded(Event event) async {
News n = News.fromSnapshot(event.snapshot);
print(n.title);
return n;
}
当我执行时,将结果2
赋予两个数据库条目
loadNews().then((List<News> newsList) {
print(newsList.length);
});
但是我得到
I/flutter (19206): 0
I/flutter (19206): Title 1
I/flutter (19206): Title 2
这意味着侦听器没有异步等待。我尝试了很多不同的方法,但是没有找到等待上一个查询结果的解决方案。
我不想在任何窗口小部件中使用setState()
,因为我想对所有窗口小部件使用自己的单例databaseHandler。因此,希望异步加载数据并在小部件中等待它。
答案 0 :(得分:0)
好的,我想我找到了解决方案。经过大量的试验和错误后,我对https://webdev.dartlang.org/articles/performance/event-loop有了一个了解。使用并强制使用嵌套的将来填充列表。然后用Completer
关闭列表。
Future<List<News>> loadNews() async {
Completer c = new Completer<List<News>>();
List<News> list = new List<News>();
Stream<Event> sse = _newsQuery.onChildAdded;
sse.listen((Event event) {
onNewsAdded(event, list).then((List<News> newsList) {
return new Future.delayed(new Duration(seconds: 0), ()=> newsList);
}).then((_) {
if (!c.isCompleted) {
c.complete(list);
}
});
});
return c.future;
}
Future<List<News>> onNewsAdded(Event event, List<News> newsList) async {
News n = News.fromSnapshot(event.snapshot);
print("ADD: "+n.title);
newsList.add(n);
return newsList;
}
我得到结果
I/flutter ( 5419): ADD: Title 1
I/flutter ( 5419): ADD: Title 2
I/flutter ( 5419): ADD: Title 3
I/flutter ( 5419): Size: 3