我有一个Future
,完成后,将一些数据添加到ChangeNotifierProvider
. 然后我使用 ChangeNotifierProvider 中的数据来填充一些ListViews
. 问题是,我有 2 个屏幕,它们都从同一个 Future 获取他们需要的数据。每个屏幕都有一个返回 ListView 的 FutureBuilder。
如何让 2 个 FutureBuilders 等待“相同”的未来,而不调用它 2 次?
FutureProvider 是解决方案吗?
问问题
371 次
1 回答
0
您应该使用Future.wait
API,它的作用是等到所有期货都完成并返回其结果或错误。
将此视为示例:
Future<String> getData() async {
final future1 = Future<String>.delayed(Duration(seconds: 1), () => "I am");
final future2 = Future<int>.delayed(Duration(seconds: 2), () => 100);
final future3 = Future<String>.delayed(Duration(seconds: 3), () => "Years old!");
final results = await Future.wait([future1, future2, future3]);
// Doing a simple cast considering my Future will never fails in this example, you should check for exceptions/errors!
final future1ResultOrError = results.first as String;
final future2ResultOrError = results[1] as int;
final future3ResultOrError = results[2] as String;
return "$future1ResultOrError $future2ResultOrError $future3ResultOrError";
}
您可以像使用单个 Future 一样使用它:
FutureBuilder(
future: getData(),
initialData: null,
builder: (context, shot) {
return Text(shot.hasData ? shot.data : "Waiting for data...");
},
),
这将打印:“我已经 100 岁了!”。注意它是如何从不同的期货加载数据的!
编辑:
您可能希望拥有一个 Future 并将其提供给两个 FutureBuilder。见下面的代码:
class _MyState extends State<MyPage> {
Future mySingleFuture;
Future<String> getData() async {
final future1 = Future<String>.delayed(Duration(seconds: 1), () => "I am");
final future2 = Future<int>.delayed(Duration(seconds: 2), () => 100);
final future3 = Future<String>.delayed(Duration(seconds: 3), () => "Years old!");
final results = await Future.wait([future1, future2, future3]);
// Doing a simple cast considering my Future will never fails in this example, you should check for exceptions/errors!
final future1ResultOrError = results.first as String;
final future2ResultOrError = results[1] as int;
final future3ResultOrError = results[2] as String;
return "$future1ResultOrError $future2ResultOrError $future3ResultOrError";
}
@override
void initState() {
super.initState();
mySingleFuture = getData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FutureBuilder(
future: getData(),
initialData: null,
builder: (context, shot) {
return Text(shot.hasData ? shot.data : "Waiting for data...");
},
),
FutureBuilder(
future: getData(),
initialData: null,
builder: (context, shot) {
return Text(shot.hasData ? shot.data : "Waiting for data 2...");
},
),
],
),
),
);
}
}
于 2020-12-30T12:49:45.100 回答