嗨,我正在为这个问题scratch之以鼻,也许这很明显,但我不确定,我从firestore检索了一个querysnapshot,它返回了一个带有snapshot.docs的querydocumentsnapshot列表,但是当我尝试映射它时,什么也没有发生,如果我在for ... in循环中使用它,那将是完美的工作。
QuerySnapshot snap =
await FirebaseFirestore.instance.collection('Products').doc(FirebaseAuth.instance.currentUser.uid).collection('ItemDetails').get();
print(snap.docs);//returns [Instance of 'QueryDocumentSnapshot', Instance of 'QueryDocumentSnapshot', Instance of 'QueryDocumentSnapshot']
for (var item in snap.docs.toList()) {//this executes perfectly
print(item.data());
}
snap.docs.toList().map((e) => print(e.data().toString()));//this wont execute
snap.docs.map((e) => print(e.data().toString()));//this wont execute
答案 0 :(得分:2)
这是因为map
方法的工作方式。根据文档-
map
方法 Iterable<T> map <T>( T f( E e ) )
使用通过调用创建的元素返回新的惰性Iterable 按迭代顺序在此Iterable的每个元素上按f。
此方法返回映射元素的视图。只要 返回的Iterable未迭代,提供的函数f将 不被调用。转换后的元素将不会被缓存。反复进行 返回的Iterable多次将调用提供的 在同一元素上多次执行f功能。
返回的iterable上的方法允许省略对任何方法的调用f 不需要结果的元素。例如,elementAt可以调用 f只有一次。
在您的示例中,因为您没有迭代结果Iterable
,所以它不会调用该函数。因此,如果您将代码更改为此
snap.docs.map((e) => print(e.data().toString())).toList();
然后它将执行,因为现在它需要遍历结果Iterable
才能将其转换为List
。
答案 1 :(得分:1)
List.map创建一个可迭代的对象,但实际上并未对其进行迭代。您可以在此示例中看到它:
List<String> s = ["a", "b", "c"];
var i = s.map((e){
print(e);
});
i.toList(); //prints a, b, c
您可以像下面这样通过调用.toList()来强制执行此操作:
List<String> s = ["a", "b", "c"];
var i = s.map((e){
print(e);
}).toList(); //prints a,b,c
print(i.length); //3