【问题标题】:Initializing a future in flutter?在颤振中初始化未来?
【发布时间】:2022-06-19 18:02:07
【问题描述】:

我想在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
}

【问题讨论】:

  • 已经尝试过了,页面只是无限期加载

标签: flutter asynchronous dart-null-safety


【解决方案1】:

一种方法是使_future 可以为空,并通过检查_future 是否为null 来使您的异步函数具有幂等性。如果它是空的,做工作;如果不为空,则返回现有的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(),
      ...
  }
}

【讨论】:

  • 实际上_future 始终是null,因为您没有为_future 分配任何值(例如_future ??= ...),或者我错过了什么?
  • @pskink 哎呀,我忘了添加那行。接得好。固定。
【解决方案2】:

尝试下面的代码,使用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 ...;
    });
}

【讨论】:

  • 给我以下错误'LateInitializationError: Field '_future@27067882' has not been initialized。'
  • 您的initState 运行了吗?您可以在initState 末尾打印_future 来检查它吗?您的_downLoadFiles 是否返回Future?无论如何,您也可以尝试使用 final _future = _downlloadFiles(); 代替 late Future&lt;dynamic&gt; _future; 并从 initState 中删除 _future
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 2023-03-08
  • 2019-01-18
  • 2021-06-21
  • 1970-01-01
相关资源
最近更新 更多