Dart函数始终返回一个Future。

huangapple go评论78阅读模式
英文:

Dart Function always returns a Future

问题

我建立了一个从Firestore获取数据并将其返回为名为Keekzs的对象列表的存储库。

所需的目标是返回一个Future<KtList<Keekz>>,但是无论出于什么原因,我始终得到返回的是Future<KtList<Future<Keekz>>>
我隔离了大部分内部部分,并在可能的地方添加了await表达式,但是没有任何改变。

有人有任何想法吗?

这是我的代码:

final keekzs = await FirebaseFirestore.instance.collection(Paths.keekzsToplevelCollection).get().then(
  (keekzsSnap) async => keekzsSnap.docs.map((keekzDoc) async {
    final keekzDocData = keekzDoc.data();
    final cardData = await keekzDoc.reference
        .collection(Paths.keekzCardsSublevelcollection)
        .get()
        .then(
          (snapshotCards) async => snapshotCards.docs,
        );
    keekzDocData.addAll({
      "keekzCards": Map.fromEntries(
        cardData.map(
          (cardDataDoc) => MapEntry(cardDataDoc.id, cardDataDoc.data()),
        ),
      )
    });
    return keekzDocData;
  }).map((keekzMapFuture) async {
    final keekzDTO = await keekzMapFuture.then(
      (keekzMap) => KeekzDto.fromFirestoreData(
        keekzMap,
        keekzMap['keekzId'].toString(),
      ).toDomain(),
    );
    return keekzDTO;
  }).toImmutableList(),
);
return keekzs;

希望这可以帮助你解决问题。

英文:

I build a repository to get data from firestore and return it as a list of objects called Keekzs.

The required aim is to have a Future<KtList<Keekz>> returned, however I am stuck at the point that for whatever reason I am always getting Future<KtList<Future<Keekz>>> to be returned.
I isolated most of the inner parts and prefix it with an await expression wherever possible, but nothing changes.

Does anyone have an idea?

Here is my code:

final keekzs = await FirebaseFirestore.instance.collection(Paths.keekzsToplevelCollection).get().then(
          (keekzsSnap) async => keekzsSnap.docs.map((keekzDoc) async {
            final keekzDocData = keekzDoc.data();
            final cardData = await keekzDoc.reference
                .collection(Paths.keekzCardsSublevelcollection)
                .get()
                .then(
                  (snapshotCards) async => snapshotCards.docs,
                );
            keekzDocData.addAll({
             "keekzCards": Map.fromEntries(
                cardData.map(
                  (cardDataDoc) => MapEntry(cardDataDoc.id, cardDataDoc.data()),
                ),
              )
            });
            return keekzDocData;
          }).map((keekzMapFuture) async {
            final keekzDTO = await keekzMapFuture.then(
              (keekzMap) => KeekzDto.fromFirestoreData(
                keekzMap,
                keekzMap['keekzId'].toString(),
              ).toDomain(),
            );
            return keekzDTO;
          }).toImmutableList(),
        );
 return keekzs;

答案1

得分: 1

就像 @jamesdlin 在评论中提到的那样:

使用具有async回调的.map()将返回一个FuturesIterable。您可以使用Future.waitIterable<Future<T>>获得List<T>

如果您观察到您的map函数返回的是Future<Keekz>而不是Keekz,那是因为您正在等待结果,这导致了期望的Future<List<Keekz>>而不是Future<List<Future<Keekz>>>

您可以使用async await的替代方法,即使用Future.wait等待map函数返回的所有futures,然后使用toImmutableList()Keekz对象的结果列表转换为不可变列表。

更新后的代码可能如下所示:

final keekzsSnap = await FirebaseFirestore.instance
    .collection(Paths.keekzsToplevelCollection)
    .get();
final keekzFutures = keekzsSnap.docs.map((keekzDoc) async {
  final keekzDocData = keekzDoc.data();
  final cardDataSnap = await keekzDoc.reference
      .collection(Paths.keekzCardsSublevelcollection)
      .get();
  final cardData = cardDataSnap.docs;
  keekzDocData.addAll({
    "keekzCards": Map.fromEntries(
      cardData.map(
        (cardDataDoc) => MapEntry(cardDataDoc.id, cardDataDoc.data()),
      ),
    ),
  });
  return keekzDocData;
});

final keekzDTOFutures = await Future.wait(keekzFutures);
final keekzs = keekzDTOFutures.map((keekzMap) =>
    KeekzDto.fromFirestoreData(
      keekzMap,
      keekzMap['keekzId'].toString(),
    ).toDomain()).toImmutableList();

return keekzs;

在这里,我将keekzsSnap的获取和映射逻辑分开,以获得简化。通过使用Future.wait(),我们等待了映射逻辑返回的所有futures,并将它们存储在keekzDTOFutures变量中。

最后,我们遍历keekzDTOFutures,将每个keekzMap转换为一个Keekz对象,并使用toImmutableList()将结果列表转换为不可变列表。

参考:wait<T> 静态方法

英文:

Like @jamesdlin mentioned in the comment :
> Calling .map() with an async callback will return an Iterable of Futures. You can use Future.wait to obtain a List&lt;T&gt; from an Iterable&lt;Future&lt;T&gt;&gt;.

If you observe your map function returning Future&lt;Keekz&gt; instead of Keekz because you are awaiting your result and that leads to Future&lt;List&lt;Future&lt;Keekz&gt;&gt;&gt; instead of the desired Future&lt;List&lt;Keekz&gt;&gt;.

Instead of async await you can use Future.wait to await all the futures returned by the map function and then convert the resulting list of Keekz objects into an immutable list with the help of toImmutableList()

The updated code may look something like :

final keekzsSnap = await FirebaseFirestore.instance
    .collection(Paths.keekzsToplevelCollection)
    .get();
final keekzFutures = keekzsSnap.docs.map((keekzDoc) async {
  final keekzDocData = keekzDoc.data();
  final cardDataSnap = await keekzDoc.reference
      .collection(Paths.keekzCardsSublevelcollection)
      .get();
  final cardData = cardDataSnap.docs;
  keekzDocData.addAll({
    &quot;keekzCards&quot;: Map.fromEntries(
      cardData.map(
        (cardDataDoc) =&gt; MapEntry(cardDataDoc.id, cardDataDoc.data()),
      ),
    ),
  });
  return keekzDocData;
});

final keekzDTOFutures = await Future.wait(keekzFutures);
final keekzs = keekzDTOFutures.map((keekzMap) =&gt;
    KeekzDto.fromFirestoreData(
      keekzMap,
      keekzMap[&#39;keekzId&#39;].toString(),
    ).toDomain()).toImmutableList();

return keekzs;

Here I have separated the fetching of keekzsSnap and mapping logic to get simplicity. By using Future.wait() we have awaited all the futures returned by mapping logic and stored in the keekzDTOFutures variable.

Finally, we map over keekzDTOFutures to convert each keekzMap into a Keekz object, and convert the resulting list into an immutable list using toImmutableList().

Reference : wait<T> static method

huangapple
  • 本文由 发表于 2023年5月28日 08:04:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定