我正在使用模型视图控制器模式,并且我有一个视图,它使用数据库中的数据来构建视图的小部件。问题是数据的获取是异步的,因此我在调用
readRequiredData()
的方法中使用 async 和 wait 关键字,以确保在执行 wait 关键字之后的任何代码之前完成数据获取。
我首先尝试将
readRequiredData()
方法放入视图小部件的构造函数中,以确保它首先执行,readRequiredData()
方法可以正常调用,但是当到达 await
关键字时,readRequiredData()
方法将退出并小部件的构建方法被调用,这会导致错误,因为页面或视图的小部件没有构建小部件所需的数据。
然后我尝试再次将其放入widget状态类的
initState()
方法中,它不会等待数据获取完成,await关键字后面的代码不会立即执行,而是退出了readRequiredData()
再次并调用构建方法。在小部件构建开始之前,如何确保数据库中的数据已按照我需要的形式完全收集?
您不能让
build
方法等待 future 完成,但您应该在 future 尚未完成时显示替代小部件。您可以使用 FutureBuilder
来完成此操作。这是一个例子:
class FutureBuilderExample extends StatefulWidget {
const FutureBuilderExample({super.key});
@override
State<FutureBuilderExample> createState() => _FutureBuilderExampleState();
}
class _FutureBuilderExampleState extends State<FutureBuilderExample> {
final Future<String> _calculation = Future<String>.delayed(
const Duration(seconds: 2),
() => 'Data Loaded',
);
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: _calculation, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
final data = snapshot.data;
return Text('This is the widget to show when the future completes. Result: $data');
} else if (snapshot.hasError) {
return Text('This is the widget to show when the error occurs.');
} else {
// This is the widget to show when the future is still pending.
return CircularProgressIndicator();
}
},
);
}
}
如果您喜欢视频说明:https://youtu.be/zEdw_1B7JHY
或者,您可以使用 Riverpod 并使用其
FutureProvider
,它将未来的计算结果包装到 AsyncData
中,以很好地处理加载、错误和数据状态。