在initState中运行异步函数 – 会有什么类型的执行?

huangapple go评论52阅读模式
英文:

Running an asynchronous function in initState - what type of execution will be?

问题

The load() function will be executed asynchronously in this case due to the use of async keyword in its declaration.

如您所述,load() 函数将在此情况下异步执行,因为在其声明中使用了 async 关键字。

英文:

Since the initState function is executed synchronously, how will load() be executed in this case - asynchronously or synchronously?

How to be sure of this?

class _ExampleState extends State<Example> {

  @override
  void initState() {
    super.initState();

    load(); //will it run synchronously or asynchronously?
  }

  Future<void> load() async {
    debugPrint('loading');
	await doIt();
  }
  ...

p.s. I was always surprised that if you ask some kind of rubbish, then immediately a lot of answers, because they are easy to answer and earn points. And if you ask something that is not quite obvious, then the question will sooner be underestimated, since it is not entirely clear what is the matter ...

答案1

得分: 1

答案是它将以异步方式执行。以下是一些我将用来解释的代码。

class MyStateful extends StatefulWidget {
  const MyStateful({super.key});

  @override
  State<MyStateful> createState() => _MyStatefulState();
}

class _MyStatefulState extends State<MyStateful> {
  @override
  void initState() {
    super.initState();

    load();
  }

  Future<void> load() async {
    debugPrint("loading");
    await doIt();
  }

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Hello"),
    );
  }
}

Future<void> doIt() async {
  await Future.delayed(const Duration(seconds: 5));
  debugPrint("done");
}

当构建MyStateful Widget时,会执行initState()函数。但是因为initState()函数内部的load()函数没有使用await,load()函数将被执行,但widget的渲染(构建)将在load()函数的结果之前开始。因此,debugPrint("done"); 将在widget渲染后执行。

这种解决方案对于不需要使用未来函数的结果来构建widget的情况没有问题,例如记录数据。

但是对于需要使用结果来构建widget的情况,例如从数据库中显示数据,考虑使用FutureBuilder!

英文:

The short answer is it will be performed asynchronously. So Here is some code I'll use to explain.

class MyStateful extends StatefulWidget {
  const MyStateful({super.key});

  @override
  State&lt;MyStateful&gt; createState() =&gt; _MyStatefulState();
}

class _MyStatefulState extends State&lt;MyStateful&gt; {
  @override
  void initState() {
    super.initState();

    load();
  }

  Future&lt;void&gt; load() async {
    debugPrint(&quot;loading&quot;);
    await doIt();
  }

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text(&quot;Hello&quot;),
    );
  }
}

Future&lt;void&gt; doIt() async {
  await Future.delayed(const Duration(seconds: 5));
  debugPrint(&quot;done&quot;);
}

When the MyStateful Widget is built, the initState() function is executed. But because the load() function inside initState() function has no await, load() function will be executed but the rendering(building) of the widget will start before the result of load(). So the debugPrint("done"); will be executed after the widget is rendered.

This solution has no problem for cases where the result of the future function is not needed for building the widget. Example: logging data.

This solution has problems where the result is needed for building the widget. Example: showing data from a database.
In this case, consider using FutureBuilder!

huangapple
  • 本文由 发表于 2023年4月17日 13:07:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76031871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定