Загрузка списка базы данных firebase с прослушивателем, асинхронным будущему - PullRequest
0 голосов
/ 17 марта 2019

Я хочу загрузить с 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 голосов
/ 17 марта 2019

Хорошо, я думаю, что нашел решение. После многих проб и ошибок я получаю представление о 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...