在 flutter 中初始化未来?

Initializing a future in flutter?

我想 运行 在 flutter 中打开页面时下载 Future 函数,但是它被调用了多次。

我想实现像本文中第二个这样的解决方案:

https://flutterigniter.com/future-async-called-multiple-times/

(初始化后记忆未来,这样init函数就不会被多次调用) 然而在他的解决方案中,他像这样初始化未来

Future<String> _future;

这在当前版本的 dart 中不再可行,我想知道是否有等效项,我尝试使用 Late 关键字并将其初始化为 null,但这两种方法都不起作用。

这是当前的代码以及我想要的代码 目前:

class _ARState extends State<AR> {
  
@override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      _downloadFiles();
    });
  }

Future<dynamic> _downloadFiles() async {
// some downloading function that is getting run multiple times ....
}


Widget build(BuildContext context) {
    return FutureBuilder<dynamic>(
      future: _downloadFiles(),
      builder: /// stuff i want built
}

我想要什么:

class _ARState extends State<AR> {
  
Future<dynamic> _future;

@override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      _downloadFiles();
    });
  }

Future<dynamic> _downloadFiles() async {
// some downloading function that is getting run multiple times ....
}


Widget build(BuildContext context) {
    return FutureBuilder<dynamic>(
      future: _future,
      builder: /// stuff i want built
}

感谢您的帮助!

尝试下面的代码,使用 late 关键字,但还有其他选项。我认为你不需要 addPostFrameCallBack:

class _ARState extends State<AR> {
  
late Future<dynamic> _future;

@override
void initState() {
  super.initState();
  _future = _downloadFiles();
}

Future<dynamic> _downloadFiles() async {

}

Widget build(BuildContext context) {
  return FutureBuilder<dynamic>(
    future: _future,
    builder: (context, snapshot) {
      if (snapshot.hasData || snapshot.data != null) {
        // build your widget
      }
      // progress indicator or something while future is running
      return ...;
    });
}

一种方法是使 _future 可以为 null,并通过检查 _future 是否为 null 使异步函数幂等。如果为空,则工作;如果它不为空,则仅 return 现有的 Future.

class _ARState extends State<AR> {
  Future<dynamic>? _future;

  ...

  Future<dynamic> _downloadFiles() {
    Future<dynamic> helper() async {
      // Do actual downloading work here.
    }

    if (_future == null) {
      _future = helper();
    }

    return _future;
  }

  Widget build(BuildContext context) {
    return FutureBuilder<dynamic>(
      future: _downloadFiles(),
      ...
  }
}