Использовать помощники итерации, такие как .map (), .where () и т. Д. В асинхронном режиме? - PullRequest
0 голосов
/ 25 февраля 2019

Short: toList() выполняется до makeMaker, в результате чего markers имеет null объектов.

Long: В Firestore у меня естьВ коллекциях table и game и внутри table имеется поле game (тип = ссылка).С StreamBuilder я могу получить доступ к table с.И я перебираю table s и пытаюсь заполнить их game поля реальными данными, используя get, как показано ниже;

if (snapshot.hasData) {
            tabledocs = snapshot.data.documents;
            markers = tabledocs
                .map((tabledoc) {
              DocumentReference gameref = tabledoc.data['game'];
              //game field is a reference type field which points to another collection
              gameref.get().then((gdoc) {
                tabledoc.data['game'] = gdoc;
                Marker marker = makeMarker(tabledoc);  //<--------Executes later
                return marker;
              });
            }).toList();                               //<--------Executes first
          }

Поскольку gameref.get().then() требует времени, toList() внизу выполняется до того, как каждый маркер сгенерирован и добавлен в markers.

Если из Firestore возвращено 3 маркера, наш markers - это массив из 3 null marker с.Я думаю, что makeMarker(..) еще не выполнил, скорее всего.

Есть ли способ для метода map дождаться завершения get s и затем инициализировать массив markers с ненулевыми значениями?Или вы можете показать мне другой способ выполнить то, что я хочу.

1 Ответ

0 голосов
/ 25 февраля 2019

Вы можете использовать

await for(var tabledoc of tabledocs) { 

}

или, если нет необходимости, чтобы элементы выполнялись по порядку (хотя результат будет в порядке оригинальных элементов)

var markers = await Future.wait(tabledocs
  .map((tabledoc) {
    DocumentReference gameref = tabledoc.data['game'];
          //game field is a reference type field which points to another collection
    var gdoc = await gameref.get();
    tabledoc.data['game'] = gdoc;
    Marker marker = makeMarker(tabledoc);
    return marker;
  });
...