我正在开发一个需要使用本地存储的颤振应用程序。由于Android中的文档目录路径将在Future中给出,因此每次我想使用该路径时,我都必须检查future是否完成。
代码可能类似于下面
class DataStructure {
late Future<Directory> _dir = getApplicationDocumentsDirectory();
Future<void> read(String fileName) async {
Directory dir = await _dir;
// Do something using dir
}
}
这可能很愚蠢,但我大部分时间都在编写 C++ 代码,所以我想减少将函数推送到事件队列的次数以获得更好的性能(我猜编译器会用以下命令来削减异步函数)await
进入“函数”以推送到事件队列)。因此,我编写了实验代码来检查等待已完成的未来是否会切断控制流。 (我的意思是,在最新版本的 Dart 中,异步函数将执行直到第一个“await”关键字出现。我想知道如果 future 已经完成,情况是否仍然如此。)
Future<void> voidFuture(String name) async {
print('$name: voidFuture');
}
Future<void> printSingle(String name, int index) async {
print('$name: -- index = $index');
}
// This emit function will print one line each time
// it gets chance to be executed.
// Because the 'await' keyword will cut the control flow,
// it can only print once each time it's executed,
// and must wait for the next chance to print again.
// This feature makes it appropriate for testing
// when and where the control flow is cut,
// as each cut will lead to one line of output.
Future<void> emit(String name, int count) async {
for (int index = 0; index != count; ++index) {
await printSingle(name, index);
}
}
Future<void> task_0() async {
const String name = 'task_0';
Future<void> emitFinish = emit(name, 3);
await voidFuture(name);
print('$name: output after await');
await emitFinish;
}
在我的环境中运行task_0(Dart SDK版本:2.18.5(稳定)在“windows_x64”上)给出如下输出:
task_0: -- index = 0
task_0: voidFuture
task_0: -- index = 1
task_0: output after await
task_0: -- index = 2
这和我的预期是一样的。当我改变时奇怪的事情发生了emit()
功能:
Future<void> emit(String name, int count) async {
for (int index = 0; index != count; ++index) {
// Before:
// await printSingle(name, index);
// After:
await Future(() {
print('$name: -- index = $index');
});
}
}
那么输出就变成了
task_0: voidFuture
task_0: output after await
task_0: -- index = 0
task_0: -- index = 1
task_0: -- index = 2
第三行对我来说毫无意义,-- index = 0
紧接着output after await
。似乎函数比构造函数的 future 更有特权?
我的主要问题是“‘await’会等待一个完成的未来吗?”,所以我写了下面的代码:
Future<String> stringFuture() async {
return '.';
}
Future<void> task_3() async {
const String name = 'task_3';
Future<void> emitFinish = emit(name, 4);
Future<String> futureString = stringFuture();
print('$name: before await of futureString');
await futureString;
print('$name: 1st await of futureString over');
await 1;
print('$name: 1st await of constant over');
await 2;
print('$name: 2nd await of constant over');
await emitFinish;
}
与第一个版本emit()
,输出是
task_3: -- index = 0
task_3: before await of futureString
task_3: -- index = 1
task_3: 1st await of futureString over
task_3: -- index = 2
task_3: 1st await of constant over
task_3: -- index = 3
task_3: 2nd await of constant over
这意味着即使await
对于常量积分,会将其后面的行推入事件队列。
(当然,有了第二个版本emit()
它的所有输出都在最后一个之后print()
in task_3()
,我不知道为什么)
我知道有很多解决方法,其中之一将使用T? value
在第一次之后分配Future<T>
完成,并检查是否value == null
每次使用它。
但我想问的问题是:
-
关键字是什么await
内部做?请提供足以解释上述现象的详细信息。
-
有什么办法可以覆盖默认值await
行为?例如,通过重写方法?
-
首选的使用方式是什么Future
值很多倍?
-
(与上面无关)如何在 Flutter 的欢迎页面停下来等待这些异步函数,例如,
getApplicationDocumentsDirectory()
在构建所有小部件之前完成?
我从谷歌得到的大多数结果都是关于async
and await
适合初学者的关键字,我找不到太多解释其行为的材料await
in Dart API 参考文档 https://api.dart.dev/stable/2.18.5/dart-async/Future-class.html.
谢谢你拯救了一颗破碎的心await
>_