好或坏:在 Dart/Flutter 中声明主方法异步

Posted

技术标签:

【中文标题】好或坏:在 Dart/Flutter 中声明主方法异步【英文标题】:Good or Bad: Declaring main method async in Dart / Flutter 【发布时间】:2019-05-14 11:13:30 【问题描述】:

我在整个app中声明了一个全局变量——SharedPreferences prefs,并在main方法中初始化。

但是,SharedPreferences 初始化返回一个 Future - 因此我尝试等待它在应用程序关闭的main 中得到解决:

SharedPreferences prefs;

void main() async 
  prefs = await SharedPreferences.getInstance();

  runApp(MyApp());

而且效果很好。我目前在生产中的 2 个应用程序中使用此方法,我突然想到使 main 方法异步可能不正确。

最后我有两个问题:

main 方法是如何被调用的,以及它在 Dart / Flutter 中的一般工作原理是什么? 使应用程序的main 方法异步会带来意外的行为吗? (到目前为止还没有)

【问题讨论】:

【参考方案1】:

在 Dart / Flutter 中 main 方法是如何被调用的以及它是如何工作的?

Dart VM(或 AOT 模式下的运行时)查找并执行名为 main 的函数。在main 返回后,VM 将等待挂起的异步操作完成后再退出。 Dart 官方网站上的Asynchronous programming 文章有一个例子说明了这一点:

    main() 执行完毕后,异步函数可以恢复执行。首先,gatherNewsReports() 返回的未来完成。然后printDailyNewsDigest() 继续执行,打印新闻。 printDailyNewsDigest() 函数体执行完毕后,它最初返回的 future 完成,应用程序退出。

(请注意exit function 将导致立即终止而无需任何等待。)


使应用程序的main方法异步会带来意想不到的行为吗? (目前还没有)

没有。首先,您应该记住,async 关键字不是使函数异步的原因。 async 关键字只允许使用await 关键字(它本身是注册Future.then 回调的语法糖)并且(大多数情况下)要求函数声明为返回Future。 (我说“大部分”是因为允许返回 void 而不是 Future<void>,尽管如果启用了 avoid_void_async lint,dartanalyzer 也会抱怨这一点。)

一旦您调用 any 异步函数,您的应用程序将本质上是异步的。当您调用异步函数时,您可以:

等待它完成(通过awaitFuture.then)。调用者也是异步的。 异步操作未等待(“即发即弃”)。但这仍然意味着main 可以在异步操作仍处于挂起状态的情况下返回。

无论哪种方式,您的应用程序都必须在终止之前等待(假设它没有遇到未捕获的异常或exit 导致的异常终止)。

由于您的main 函数使用await,您甚至无法选择将其标记为async

【讨论】:

很好的信息。随着我的应用程序的增长,我发现自己需要从 main 方法进行异步调用。没有发生什么不好的事情,但我一直想知道它是否会破坏某些东西。 官方文档提供了将main方法改为async方法的例子Working with futures: async and await @KexiHe 这与我写的任何内容都没有冲突。我从未说过不应将main 标记为async 或不应返回Future【参考方案2】:

来自@jamesdlin 的好作品。

你的问题的字面答案

main 方法是如何被调用的以及它在 Dart 中的一般工作方式 / 颤动?

对于 android 应用,Dart 入口点通过DartExecutor 调用。你可以看看这里:DartExecutor class

有一个简短的文档,你可以如何手动完成 FlutterApplication 为你做的事情: wiki/Experimental:-Launch-Flutter-with-non-main-entrypoint

如果您想深入挖掘,您想查找的课程:FlutterApplicationFlutterActivityFlutterMain

【讨论】:

以上是关于好或坏:在 Dart/Flutter 中声明主方法异步的主要内容,如果未能解决你的问题,请参考以下文章

O/R 映射器 - 好或坏

如何在 dart/flutter 中声明 64bit unsigned int?

Dart/flutter:如何在模拟器的本地主机上显示来自 API 的图像

Dart/Flutter - 回调函数中的“yield”

Dart/Flutter 中用于 FHIR 资源的 Json oneOf

异步/等待/然后在 Dart/Flutter 中