我如何在 FutureBuilder Widget 的构建器函数中等待 - Flutter
Posted
技术标签:
【中文标题】我如何在 FutureBuilder Widget 的构建器函数中等待 - Flutter【英文标题】:How can I await inside the builder function of FutureBuilder Widget - Flutter 【发布时间】:2021-06-27 04:45:26 【问题描述】:我试图在 FutureBuilder 内两次从 firebase 检索数据,第一次是“future:”参数负责检索数据。但是,当我第二次尝试从 firebase 检索“restaurant”数据时,我收到一个 null 错误,因为我不能等待“getRestauran()”函数完成执行。如果我在函数之前添加“等待”,则会出现错误,因为“异步”无法应用于“构建器”函数。
有没有办法让它工作?
Future<Restaurant> getRestaurant(String restaurantId) async
Map<String, dynamic> restaurantData;
String id;
await FirebaseFirestore.instance
.collection('restaurants')
.doc(restaurantId)
.get()
.then((value)
restaurantData = value.data();
id = value.id;
);
print(restaurantData);
final restaurant1 = Restaurant(
id: id,
name: restaurantData['name'],
description: restaurantData['description'],
// cuisine: List<String>.from(restaurant['cuisine']),
imageUrl: restaurantData['imageUrl'],
isAvailable: restaurantData['isAvailable'],
isFavourite: restaurantData['isFavourite'],
pickupTime: restaurantData['pickupTime'].toDate(),
stars: restaurantData['stars'].toDouble(),
location: Location(
address: restaurantData['location']['address'],
city: restaurantData['location']['city'],
latitude: restaurantData['location']['latitude'],
longitude: restaurantData['location']['longitude'],
zipcode: restaurantData['location']['zipcode'],
locality: restaurantData['location']['locality'],
),
// items: restItems,
// reviews: reviews,
);
return restaurant1;
@override
Widget build(BuildContext context)
final cart = Provider.of<Cart>(context);
final order = Provider.of<Order>(context);
// cartItems =
// Provider.of<Cart>(context, listen: false).cartItems.values.toList();
//print(cartItems[0].title);
final Size size = MediaQuery.of(context).size;
return Scaffold(
body:
// cartItems.isEmpty
// ? Center(
// child: Text(
// 'Your Cart is Empty',
// style: TextStyle(
// color: kTextLightColor,
// fontSize: 18,
// ),
// ),
// )
// :
FutureBuilder<List<CartItem>>(
future: cart.fetchCartItems(),
builder: (context, snapshot)
if (!snapshot.hasData)
//Navigator.of(context).pushNamed('loading');
return Center(child: CircularProgressIndicator());
List<CartItem> cartItems = snapshot.data;
print(cartItems[0].restaurantId);
Map<String, dynamic> restaurantData;
String id;
restaurant = getRestaurant(cartItems[0].restaurantId);
print('$restaurant: Restaurant Data');
// return isComplete
return CartWidget(
restaurant: restaurant,
cart: cart,
cartItems: cartItems,
order: order);
// : CircularProgressIndicator();
),
);
【问题讨论】:
【参考方案1】:一般来说,您不能在构建方法中使用await
。您可以调用函数,但不能等待它们。 Future builder 解决了这个问题。
在你的情况下,你需要两个未来的建设者,而你已经找到了第一个。
The solution is to go to your `CartWidget`, when you define it, add a required string to it like this, instead of requiring a `restaurant` object, you require a `restaurantId`:
class CartWidget extends StatelessWidget
final String restaurantId;
const CartWidget(required this.restaurantId);
//.
//.
// the rest of your widget logic, also move this function completely to this widget
//Future<Restaurant> getRestaurant(String restaurantId) async
然后,在您的构建中,当涉及到餐厅时,请使用未来的构建器,并使用您移至此处的功能来获取它。它会解决你的问题。
【讨论】:
链接FutureBuilder
s 不是一个好的解决方案-相反,您应该将Future
s 链接在一个async
方法中-如果您有一个包含3 个或更多嵌套@987654326 的链怎么办@s?你会使用 3 个或更多嵌套的 FutureBuilder
s 吗?
你能指出链接 F.Builders 的问题吗?将它们链接在一起有什么问题,但是可以链接异步函数来构建它们?它实际上可以更好地控制屏幕上显示的内容,并且不会过度获取数据,尤其是在每个请求都很重要的情况下,当涉及到 firebase 时。这就是 F.Builders 的用途,您不必等待所有功能完成。无论完成什么,都会显示在屏幕上。请提供你的论点,我对你的观点很感兴趣,如果你能证明我的观点,我准备改变我的观点
我是 Flutter 新手,所以我对这个 lol 了解不多。我在考虑保存请求,你说的也有道理,这就是我打算包括餐厅信息的原因。在我的购物车收藏中。但是,如果您能为我提供一个更好的解决方案来节省 firebase 中的读写次数,我将不胜感激。谢谢:)
ok 以sqflite
包为例,假设它应该显示基于上一个会话的数据(例如,您的应用显示一些电子书,并且在上一个会话中您存储在shared_preferences
电子书路径(电子书作为 sqlite db 分发,用于快速文本搜索)和您停止阅读的页码)
[继续...] 所以你必须首先阅读那些为你提供书籍路径和页码的共享偏好 - 这是Future
“one”,然后基于你必须打开那个 sqlite 数据库 - 这是Future
“二”,最后当你拥有那个数据库时,你从最后一个阅读页面读取内容 - 这是一个 Future
“三” - 现在你真的会创建 3 FutureBuilder
s 吗?或者你只做await shared_prefs
,然后是await open_db
,然后是await readContent
——所有这些都在一个async
方法中以上是关于我如何在 FutureBuilder Widget 的构建器函数中等待 - Flutter的主要内容,如果未能解决你的问题,请参考以下文章
FlutterFuture 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )
如何在 FutureBuilder() 中正确“刷新”小部件
如何在 FutureBuilder Flutter 中停止循环 SetState
如何在 FutureBuilder 中解析从本地主机接收的 JSON 对象