英文:
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()
将返回一个Futures
的Iterable
。您可以使用Future.wait
从Iterable<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<T>
from an Iterable<Future<T>>
.
If you observe your map
function returning Future<Keekz>
instead of Keekz
because you are awaiting your result and that leads to Future<List<Future<Keekz>>>
instead of the desired Future<List<Keekz>>
.
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({
"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;
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论