Dart 如何 return Future<List<MyProductTile>> 而不是 List<Future<MyProductTile>>
Dart how to return Future<List<MyProductTile>> instead of List<Future<MyProductTile>>
我有一个异步函数 getProducts()
应该 return 一个 Future<List<MyProductTile>>
意味着被提供给 FutureProvider。
到目前为止,我设法 return 一个 List<Future<MyProductTile>>
代替:
Future<List<MyProductTile>> getProducts(
Stream<DocumentSnapshot> stream) async {
var documentSnapshot = await stream.first;
List<DocumentReference> productsDocRefsList =
List<DocumentReference>.from(documentSnapshot.data['used_products']);
var x = productsDocRefsList
.map((documentReference) => documentReference.get().then(
(documentSnapshot) =>
MyProductTile.fromFirestore(documentSnapshot)))
.toList();
print(x.runtimeType); // List<Future<MyProductTile>>
}
我尝试按照建议使用 Future.wait in this Whosebug answer 但我没有成功。
一种方法是利用 asyncMap from the Dart Stream API。这特别有用,因为您将 DocumentSnapshot
流作为函数的参数。
Future<List<MyProductTile>> getProducts(Stream<DocumentSnapshot> stream) {
return stream
.expand((documentSnapshot) => documentSnapshot.data['used_products'])
.asyncMap((documentReference) => documentReference.get())
.map((documentSnapshot) => MyProductTile.fromFirestore(documentSnapshot))
.toList();
}
通过等待每个 Future 来转换 Futures 列表。
Future<List<Object>> dataFromFutures(List<Future<Object>> futures) async {
List<Object> dataList = [];
futures.forEach((Future i) async {dataList.add(await i);});
return dataList;
}
Future getDetails() async {
var firestore = Firestore.instance;
QuerySnapshot qs = await firestore
.collection('letters_sub')
.where('sub_id', isEqualTo: widget.letters.id)
.getDocuments();
return qs.documents;
}
Container(
child: FutureBuilder(
future: getDetails(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: Text('Loading...'),
);
} else {
return ListView.builder(
//padding: EdgeInsets.symmetric(horizontal: 16.0),
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
var sub_text_en = snapshot.data[index].data['sub_text_en'];
return Column(
textDirection: TextDirection.rtl,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
snapshot.data[index].data['sub_text_ar'],
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 14.0,
//color: Colors.blue,
fontWeight:
FontWeight.normal),
),
Text(
sub_text_en.contains('\n') ? sub_text_en : sub_text_en.replaceAll('\n ', '\n') ,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 14.0,
// color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
],
);
});
}
}),
),
我有一个异步函数 getProducts()
应该 return 一个 Future<List<MyProductTile>>
意味着被提供给 FutureProvider。
到目前为止,我设法 return 一个 List<Future<MyProductTile>>
代替:
Future<List<MyProductTile>> getProducts(
Stream<DocumentSnapshot> stream) async {
var documentSnapshot = await stream.first;
List<DocumentReference> productsDocRefsList =
List<DocumentReference>.from(documentSnapshot.data['used_products']);
var x = productsDocRefsList
.map((documentReference) => documentReference.get().then(
(documentSnapshot) =>
MyProductTile.fromFirestore(documentSnapshot)))
.toList();
print(x.runtimeType); // List<Future<MyProductTile>>
}
我尝试按照建议使用 Future.wait in this Whosebug answer 但我没有成功。
一种方法是利用 asyncMap from the Dart Stream API。这特别有用,因为您将 DocumentSnapshot
流作为函数的参数。
Future<List<MyProductTile>> getProducts(Stream<DocumentSnapshot> stream) {
return stream
.expand((documentSnapshot) => documentSnapshot.data['used_products'])
.asyncMap((documentReference) => documentReference.get())
.map((documentSnapshot) => MyProductTile.fromFirestore(documentSnapshot))
.toList();
}
通过等待每个 Future 来转换 Futures 列表。
Future<List<Object>> dataFromFutures(List<Future<Object>> futures) async {
List<Object> dataList = [];
futures.forEach((Future i) async {dataList.add(await i);});
return dataList;
}
Future getDetails() async {
var firestore = Firestore.instance;
QuerySnapshot qs = await firestore
.collection('letters_sub')
.where('sub_id', isEqualTo: widget.letters.id)
.getDocuments();
return qs.documents;
}
Container(
child: FutureBuilder(
future: getDetails(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: Text('Loading...'),
);
} else {
return ListView.builder(
//padding: EdgeInsets.symmetric(horizontal: 16.0),
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
var sub_text_en = snapshot.data[index].data['sub_text_en'];
return Column(
textDirection: TextDirection.rtl,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
snapshot.data[index].data['sub_text_ar'],
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 14.0,
//color: Colors.blue,
fontWeight:
FontWeight.normal),
),
Text(
sub_text_en.contains('\n') ? sub_text_en : sub_text_en.replaceAll('\n ', '\n') ,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 14.0,
// color: Colors.blueGrey,
fontWeight: FontWeight.bold),
),
],
);
});
}
}),
),