使用与未来异步的侦听器加载Firebase数据库列表

时间:2019-03-16 22:16:52

标签: firebase-realtime-database dart flutter

我想从实时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。因此,希望异步加载数据并在小部件中等待它。

1 个答案:

答案 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