颤振/飞镖异步不等待
Posted
技术标签:
【中文标题】颤振/飞镖异步不等待【英文标题】:Flutter/Dart Async Not Waiting 【发布时间】:2019-05-07 00:18:27 【问题描述】:我正在构建我的第一个 Flutter 应用程序,但遇到了一些异步问题。
当我的应用程序执行时,我希望它请求权限并等待它们被授予。我的 main() 函数如下所示:
import 'permission_manager.dart' as Perm_Manager;
void main() async
//Ensure valid permissions
Perm_Manager.Permission_Manager pm = Perm_Manager.Permission_Manager();
var res = await pm.get_permissions();
print(res);
return runApp(MyApp());
Permission Manager 类的 get_permissions() 函数使用 Flutter Simple Permissions 包来检查和请求权限。
import 'package:simple_permissions/simple_permissions.dart';
import 'dart:io' as IO;
import 'dart:async';
class Permission_Manager
/* Get user permissions */
Future<bool> get_permissions() async
//android handler
if (IO.Platform.isAndroid)
//Check for read permissions
SimplePermissions.checkPermission(Permission.ReadExternalStorage).then((result)
//If granted
if (result)
return true;
//Otherwise request them
else
SimplePermissions.requestPermission(Permission.ReadExternalStorage)
.then((result)
// Determine if they were granted
if (result == PermissionStatus.authorized)
return true;
else
IO.exit(0); //TODO - display a message
);
);
else
return true;
当我运行应用程序时,它不会等待函数按预期完成,而是在 Future 更新之前打印“res”的值。
Launching lib\main.dart on Android SDK built for x86 in debug mode...
Built build\app\outputs\apk\debug\app-debug.apk.
I/SimplePermission(15066): Checking permission : android.permission.READ_EXTERNAL_STORAGE
I/flutter (15066): null
I/SimplePermission(15066): Requesting permission : android.permission.READ_EXTERNAL_STORAGE
Future 在函数中途返回一个值!有谁知道我做错了什么?
【问题讨论】:
【参考方案1】:要等待某事,您必须在未来调用 await
关键字而不是 .then
final result = await future;
// do something
而不是
future.then((result)
// do something
);
如果你真的想使用.then
,那么你可以等待生成的未来:
await future.then((result)
// do something
);
只需确保在使用嵌套异步调用时,每个调用都使用 async 关键字:
await future.then((result) async
// do something
await future.then((result_2)
// do something else
);
);
【讨论】:
"await" 用于调用异步函数的 main() 函数。尽管我的印象是“then”和“await”虽然语法不同(“then”在完成后运行一个函数)但它们的操作方式相同。 不,他们没有。你真的必须使用await
来自 Dart 文档 (dartlang.org/tutorials/language/futures):“要暂停执行直到未来完成,请在异步函数中使用 await(或使用 then())。”但尽管如此,我确实在 main() 函数中使用了 await 无济于事。
一次是不够的。在您的示例中,您需要的不仅仅是一个 await
我认为你不能等待生成的未来。生成的未来对于 then() 运行的回调函数是本地的,并且执行诸如“await SimplePermissions.checkPermission(Permission.ReadExternalStorage).then((result) ...”之类的操作会产生错误。确实可以返回从回调生成未来,但由于插件不返回布尔值,您需要重写 main() 中的大部分函数【参考方案2】:
搞定了。该问题似乎已使用 Completer 解决:
import 'package:simple_permissions/simple_permissions.dart';
import 'dart:io' as IO;
import 'dart:async';
class Permission_Manager
/* Get user permissions */
final Completer c = new Completer();
Future get_permissions() async
//Android handler
if (IO.Platform.isAndroid)
//Check for read permissions
SimplePermissions.checkPermission(Permission.ReadExternalStorage).then((result)
//If granted
if (result)
c.complete(true);
//Otherwise request them
else
SimplePermissions.requestPermission(Permission.ReadExternalStorage).then((result)
// Determine if they were granted
if (result == PermissionStatus.authorized)
c.complete(true);
else
IO.exit(0); //TODO - display a message
);
);
else
c.complete(true);
return c.future;
【讨论】:
这会使get_permissions
上的async
标志无用。
应用程序需要任何功能的读取权限,但简单权限插件异步操作。具体来说,打开应用程序时会读取下载目录中的所有文件。此解决方案会阻止应用程序读取目录,直到授予权限。如果有一种方法可以同步使用插件,那将是理想的,但我认为这是不可能的。
我不是说代码不行,而是语法不对。
参考文档 (pub.dartlang.org/packages/simple_permissions#-readme-tab-)。在没有 async 标志的情况下运行代码并返回非未来 bool 会产生与初始问题中看到的相同的结果(由于插件代码异步运行)。还有其他方法吗?以上是关于颤振/飞镖异步不等待的主要内容,如果未能解决你的问题,请参考以下文章