【问题标题】:build method doesn't wait for async构建方法不等待异步
【发布时间】:2019-08-30 12:04:00
【问题描述】:

我是 Flutter 的新手,我对 async 和 await 有一些问题。 我想,首先从服务器获取一些数据,然后构建我的小部件,但我的构建方法不等待 getData 并且我的构建中的一个小部件无法在没有任何数据的情况下运行。 我想要一个等到数据来自服务器然后运行构建方法的函数。

Map<String,dynamic> data = Map<String,dynamic>();
 Future getData() async{
    String url = "http://10.0.2.2:8080/facts/get.php";
    http.Response responseData = await http.get(url);
  setState(() {
     data = json.decode(responseData.body); 
  });
}
@override
void initState()  {
  super.initState();
  getData();
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我建议使用FutureBuilder 而不是将async 函数放在initState 中。为此,您需要更改 getData 方法。

    示例

    您的状态有一个名为 dbFuture 的 Future 变量

    Future<Map<String, dynamic>> dbFuture;
    

    你的getData 方法应该是这样的:

     Future<Map<String,dynamic>> getData() async{
        String url = "http://10.0.2.2:8080/facts/get.php";
        http.Response responseData = await http.get(url);
        return json.decode(responseData.body); 
    }
    

    让我们在 initState 中发出网络请求,无需等待结果,只需将其分配给我们的 Future 变量:dbFuture

    initState(){
      dbFuture = getData();
      super.initState();
    }
    

    build 方法中:

    FutureBuilder(
          future: dbFuture,
          builder: (BuildContext context,AsyncSnapshot snapshot){
            if(snapshot.connectionState != ConnectionState.done){
              return Container(); // your widget while loading
            }
    
            if(!snapshot.hasData){
              return Container(); //your widget when error happens
            }
    
            final data = snapshot.data; //your Map<String,dynamic>
            return yourScreen(); //place your widget here
          },
        );
    

    您可以参考文档中的FutureBuilder 小部件以获取更多信息。

    注意:我们不使用方法作为 Future,而是使用 Future 变量并在 initState() 中进行异步调用,这样我们会提前一点发出请求并防止不必要的网络调用。

    【讨论】:

    • 我认为在 initState 中调用 getData 而无需等待结果,只需将其分配给 Future 变量,然后在 FutureBuilder 中使用该变量会更好。它将防止不需要的网络调用
    • @mirkancal FutureBuilder 只调用Future 一次。我认为它比在initState 中调用setState 更干净,因为您可以在StatelessWidget 中使用它,从而完全无状态。此外,如果在第一个 Widget 构建之前调用 setStateinitState 内调用,可能会导致问题。
    • 我没有在我的代码中调用 setState,我不需要它。此外,如果您的 futurebuilder 在 build 方法中,它可以被重建,这将导致意外的请求从每个 build 方法调用中触发。由于 futurebuilder 将在其 future 属性中调用该函数。但是如果你给一个future,而不是一个方法,它只会使用future,不需要调用函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    相关资源
    最近更新 更多