使用慢速异步方法的 Flutter 进度指示器

Flutter progress indicator with slow async method

当我尝试将 CircularProgressIndicator 与慢速异步方法一起使用时,未显示指示器。当我用 Timer.pereodic() 替换慢速自定义方法时效果很好。我是 Flutter 的新手,不明白我做错了什么

class _MyHomePageState extends State<MyHomePage> {
  bool _inProgress = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          width: 200,
          height: 200,
          child: Column(
            children: [
              _inProgress ? CircularProgressIndicator() : Text("ready"),
              FloatingActionButton(onPressed: _slowMethod)
            ],
          ),
        ),
      ),
    );
  }

  int fibonacci(int n) {
    return n <= 2 ? 1 : fibonacci(n - 2) + fibonacci(n - 1);
  }

  _slowMethod() async {
    setState(() {
      _inProgress = true;
    });

    for (int i = 20; i <= 100; ++i) {
      print(fibonacci(i));
    }

    setState(() {
      _inProgress = false;
    });
  }
}

An async function runs synchronously until the first await keyword.

首先,_slowMethod 中没有 await 关键字,从技术上讲,这意味着您需要将“what-should-be-asynchronous”操作包装在 [=14= 中] 和 await

所以您的解决方案应该是 _slowMethod() 的以下内容:

  _slowMethod() async {
    setState(() {
      _inProgress = true;
    });

    await Future(() {
      for (int i = 20; i <= 100; ++i) {
        print(fibonacci(i));
      }
    });

    setState(() {
      _inProgress = false;
    });
  }

但是正如 Richard Heap (@Richard Heap) 在评论中指出的那样,上面的方法会遇到问题。如果您 运行 代码,CircularProgressIndicator 将无法显示,因为主 Dart 线程已被要求苛刻的斐波那契数列劫持,您的 UI 将无法正确呈现。

我假设您在生产代码中可能真的没有高达 100 的斐波那契数列。那可能是您用它来向我们展示问题所在。但即使是这种情况,或者您有复杂的异步操作,您也可以像 Richard 提到的那样使用 Isolates。

如果异步操作对主线程的要求不是很高(比如简单地做Future.delayed),等待未来应该可以。

以下代码段将按您的预期运行。

  _slowMethod() async {
    setState(() {
      _inProgress = true;
    });

    await Future.delayed(const Duration(seconds: 3));

    setState(() {
      _inProgress = false;
    });
  }