我不希望每次重建小部件时都触发异步调用。 因此,我在 initState 中调用异步函数。
在 initState 中调用异步
@override void initState() { someAsyncCall().then((result) { setState() { _result = result; } }); } @override Widget build(BuildContext context) { if (_result == null) { reutrn new Container(); } return new SomeWidget(); }
使用 FutureBuilder
@override void initState() { _future = someAsyncCall(); } @override Widget build(BuildContext context) { return new FutureBuilder( future: _future, builder: // do something ); }
这两种解决方案是否有任何副作用或不良做法?
我修改了 flutter 的 demo app 来解释为什么我在 initSate 中调用 async。
1. 打开app,打印main
2. 推屏测试,打印测试,main
3. pop测试,打印main
如果我在构建中调用异步函数,它会调用三次。
我想要的是,我需要异步函数调用一次,除非主要处理/弹出。
根据 Rémi Rousselet 的回答,在 initState 中调用 async 是一种问题或错误。
那么,如何确保异步函数只调用一次呢?
@override
Widget build(BuildContext context) {
print("build main");
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(onPressed: () {
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new Test();
}));
}),
],
),
)
);
}
class Test extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("build Test");
return new Scaffold(
body:
new FlatButton(onPressed: () {
Navigator.pop(context);
}, child: new Text("back"))
);
}
}
我需要做类似的事情吗
@override
Widget build(BuildContext context) {
if (!mounted) {
print("build main");
// aysnc function call here
}
}
最佳答案
虽然有点冗长,FutureBuilder
绝对是正确的选择。
在 initState 中调用异步函数,然后在完成时执行 setState
有一些问题。大多数情况下,执行此操作时,您不会为错误捕获或处理加载时间而烦恼。
请记住,Flutter 期望 initState
是同步的。因此,虽然 dart 不会阻止您对同步函数进行异步调用,但 flutter 很可能会认为您的小部件已准备就绪,但实际上并没有。
关于flutter - Flutter 异步调用的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51977379/