flutter - Flutter 异步调用的最佳实践?

标签 flutter

我不希望每次重建小部件时都触发异步调用。 因此,我在 initState 中调用异步函数。

  1. 在 initState 中调用异步

    @override
    void initState() {
      someAsyncCall().then((result) {
        setState() {
         _result = result;
        }
      });
    }
    
    @override
    Widget build(BuildContext context) {
      if (_result == null) {
        reutrn new Container();
      }
    
      return new SomeWidget();
    }
    
  2. 使用 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/

相关文章:

flutter - 更改AppBar标题填充

animation - flutter 动画插值

flutter - DateTime 类参数应该是 const 但 DateTime 不支持这个

dart - 测试构建 Flutter 小部件会抛出异常

flutter - 确定一个 Map 是否是另一个 Map 的子集

ios - 我应该提交 ios/Runner.xcworkspace/xcshareddata/吗?

flutter - Provider中的监听器如何在Flutter中工作?

apply() 和 copyWith() 之间的 Flutter TextStyle(不是 TextTheme)区别

flutter - 如何使用打开路径的元数据启动应用程序?

flutter - getter 'email'在null-Flutter/Firebase上被调用