我正在经历有趣的行为。我在有状态的小部件中有一个FutureBuilder。如果我一个人返回FutureBuilder,一切正常。我的API仅被调用一次。
但是,如果我添加了额外的逻辑,并在两个小部件之间进行选择-我可以在chrome中看到我的API被调用了数十次。我知道cat foo.txt | tail -n +2 | awk '$17 ~ /^[F][0-9][0-9][0-9]$/' >> foo_new.txt
cat foo_new.txt | awk '{print $4=$3-$2+1, $5=$1/($3-$2+1)}' >> foo_new.txt
方法可以随时执行,但是这种额外的逻辑如何完全破坏Future的行为呢?
这里是api调用一次的示例。
build
以下是如果@override
Widget build(BuildContext context) {
return FutureBuilder(..);
}
为someBooleanFlag
时api被多次调用的示例。
false
谢谢
答案 0 :(得分:3)
即使您的代码最初工作时,您仍然无法正确执行它,正确的方法是:
// Create instance variable
Future myFuture;
@override
void initState() {
super.initState();
// assign this variable your Future
myFuture = getFuture();
}
@override
Widget build(BuildContext context) {
if (someBooleanFlag) {
return Text('Hello World');
} else {
return FutureBuilder(
future: myFuture, // use it like this
...
);
}
}
答案 1 :(得分:2)
使用AsyncMemoizer 一个用于只运行一次异步函数并缓存其结果的类。
AsyncMemoizer _memoizer;
@override
void initState() {
super.initState();
_memoizer = AsyncMemoizer();
}
@override
Widget build(BuildContext context) {
if (someBooleanFlag) {
return Text('Hello World');
} else {
return FutureBuilder(
future: _fetchData(),
builder: (ctx, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
return CircularProgressIndicator();
},
);
}
}
_fetchData() async {
return this._memoizer.runOnce(() async {
await Future.delayed(Duration(seconds: 2));
return 'DATA';
});
}
未来的方法:
_fetchData() async {
return this._memoizer.runOnce(() async {
await Future.delayed(Duration(seconds: 2));
return 'REMOTE DATA';
});
}
此memoizer
正是我们想要的!它具有一个异步函数,在首次调用它时将其缓存并缓存其结果。对于随后所有对该函数的调用,memoizer
返回相同的先前计算出的future。
详细说明:
https://medium.com/flutterworld/why-future-builder-called-multiple-times-9efeeaf38ba2