未来的构建者(未来:)正在递归我的http请求,

时间:2019-02-11 15:11:35

标签: dart flutter

在页面渲染之前,我需要从三个不同的url获取数据。所以, 这是我的ScopedModel内的方法,其中包含多个http.post方法:

Future fetchData() async {
  _isLoading = true;
  notifyListeners();
  await fetchAvailable();
  await fetchOnProgress();
  await fetchCompleted();
  _isLoading = false;
  notifyListeners();

}

fetchData区域内的方法只是具有原始Future类型的经典http.post请求。

这是我的FutureBuilder:

FutureBuilder(
        future: model.fetchData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          return snapshot.connectionState != ConnectionState.done
              ? Center(
                  child: CircularProgressIndicator(),
                )
              : Column.......

问题是“未来”功能,它不断执行且永无止境。我从服务器获取json的算法将正文中的变量膨胀为ListView.builder后代。

输出如我所说的递归发布请求。另外,我正在获取此日志,行数以1-2-3或2-4-6 -8等递增。

uid=10085(my.package.directory) 1.ui identical 1 lines
.......Other logs here
uid=10085(my.package.directory) 1.ui identical 3 lines

然后继续...

还有,还有其他有用的方法来处理页面呈现之前的少量数据吗?

2 个答案:

答案 0 :(得分:2)

请勿在{{1​​}}中发出HTTP请求

https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html

  

将来一定要早一些,例如中   State.initState,State.didUpdateConfig或   State.didChangeDependencies。不得在   构造状态时调用State.build或StatelessWidget.build方法   FutureBuilder。如果未来与   FutureBuilder,那么每次重新构建FutureBuilder的父项时,   异步任务将重新启动。

答案 1 :(得分:0)

这是一个可能的正确解决方案。这使您的数据仅在脚手架内加载一次。首先,请确保您使用的是有状态窗口小部件。

定义数据:

Future<List<Data>> futureList;

提供一个从后端获取数据的功能:

Future<void> getList() async {
    final provider = Provider.of<DataProvider>(context, listen: false);
    final list = provider.getData();
    setState((){
      futureList = list;
    });
  }

在初始化状态下加载函数:

@override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      getList();
    });
  }

在将来的构建器中调用您获取的数据:

Widget _body(BuildContext context) {
    return FutureBuilder(
      future: futureList,
      builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
        if (snapshot.hasData) {
          if(snapshot.data.length == 0){
            return Center(child: Text('List is empty'));
          }else {
            return ListView.builder(
                padding: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
                itemBuilder: (BuildContext context, int index) {
                  return GestureDetector(
                      child: DataItem(
                        index: index,
                        dataClass: snapshot.data[index],
                      ),
                      onTap: () {});
                },
                itemCount: snapshot.data.length);
          }
        } else {
          return Center(child: CircularProgressIndicator());
        }
      },
    );