将来运行两次,因为它在构建方法中,如何解决?

时间:2019-11-05 18:24:57

标签: flutter

说我有一个可以制作一些大文件的功能

Future<File> makeBigFile() async {
    // lots of processing
    return File("generated_file.txt");
}

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: makeBigFile(),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (snapshot.hasData && snapshot.data is File) {
        return Text("Success!");
      } else if (snapshot.connectionState==ConnectionState.done) {
        return Text("Error!");
      } else {
        return CircularProgressIndicator();
      }
    }
  );
}

因此,每当构建运行时,未来也将运行,但显然不应该。文档说

  

将来一定要早一些,例如在State.initState,State.didUpdateConfig或State.didChangeDependencies中。构造FutureBuilder时,不得在State.build或StatelessWidget.build方法调用期间创建它。如果Future是与FutureBuilder同时创建的,则每次FutureBuilder的父代重建时,异步任务都将重新启动。

据我了解(尽管阅读并重新阅读了文档,但不多)FutureBuilder必须位于build()中,并且需要具有future:才能运行多个时间没有问题,但是如果应该进行多次长时间的操作怎么办?

我应该如何更改我的代码,使其执行现在的操作,而又不会多次运行将来的代码?

2 个答案:

答案 0 :(得分:2)

class BigFileWidget extends StatefulWidget {
  @override
  _BigFileWidgetState createState() => _BigFileWidgetState();
}

class _BigFileWidgetState extends State<BigFileWidget> {

  Future<File> fileFuture;

  @override
  void initState() {
    fileFuture = makeBigFile();
  };

  Future<File> makeBigFile() async {
    // lots of processing
    return File("generated_file.txt");
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: fileFuture,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData && snapshot.data is File) {
            return Text("Success!");
          } else if (snapshot.connectionState==ConnectionState.done) {
            return Text("Error!");
          } else {
            return CircularProgressIndicator();
          }
        }
    );
  }
}

答案 1 :(得分:1)

File myFile;
bool isLoading = false;

Future<File> makeBigFile() async {
    isLoading = true;
    // lots of processing with await methods
    myFile = File("generated_file.txt");
    setState({
        isLoading = false;
    });
}

@override
void initState() {
    makeBigFile();
};

@override
Widget build(BuildContext context) {
    return isLoading 
        ? CircularProgressIndicator()
        : Text( myFile == null ? "Error" : "Success");
}