首页 > 解决方案 > 好或坏:在 Dart/Flutter 中声明主方法异步

问题描述

我在整个应用程序中声明了一个全局变量 - SharedPreferences prefs,并在main方法中对其进行了初始化。

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

SharedPreferences prefs;

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

  runApp(MyApp());
}

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

最后我有2个问题:

标签: dartflutter

解决方案


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

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

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

(请注意,该exit函数将导致立即终止,无需任何等待。)


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

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

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

  • 等待它完成(通过awaitFuture.then)。调用者也是异步的。
  • 异步操作无需等待(“即发即弃”)。但这仍然意味着main可以返回异步操作仍然挂起。

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

由于您的main函数使用await,您甚至没有选择标记它async


推荐阅读