一般来说,您不应该编写这样的代码,因为您依赖于异步事件的执行顺序。如果你依赖某件事发生,你应该等待依赖的未来来获取值。
原因是您的代码确实按照您描述的顺序执行。但是我们也可以创建一个Future.sync,它会改变同一个程序的执行方式(根据构造函数的名称,这并不奇怪):
void main() {
final myFuture = Future.sync(() {
print("Executing Future");
return 10;
});
print("Exiting main now");
}
// Returns:
// Executing Future
// Exiting main now
在将Future 返回给调用代码之前,您无法真正看到正在执行多少代码。这就是为什么在异步代码方面除了等待所需的期货/流来获取值之外,您永远不应该依赖执行顺序的主要原因。
但是,是的,如果这只是一个理论上的问题,那么根据 Future 构造函数的 API 描述,您的具体代码将始终按照您所说的那样执行:
创建一个包含使用 Timer.run 异步调用计算结果的未来。
https://api.dart.dev/stable/2.14.4/dart-async/Future/Future.html
我一般可以推荐以下关于 Dart 中的事件循环的文章:
https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a
更新 1
我这么说的原因:
在将 Future 返回给调用代码之前,您无法真正看到正在执行多少代码。
是因为我们可以这样做:
import 'dart:async';
void main() {
print('Step 1');
myAsyncMethod().then(print);
print('Step 3');
}
Future<String> myAsyncMethod() async {
print('Step 2');
await Future.delayed(const Duration(milliseconds: 1), () => null);
return 'Step 4';
}
将输出:
Step 1
Step 2
Step 3
Step 4
出现这种行为的原因是,async 方法将作为同步方法运行,直到第一个 await 操作之后它会像异步函数一样运行。因此,当我们调用myAsyncMethod 时,我们会立即执行print('Step 2'),但随后我们会返回并执行print('Step 3')。
所以如果我们只看:
myAsyncMethod().then(print);
在获得Future 之前,我们并不真正知道执行了什么操作。还应该注意,这不是async 标记方法所独有的。我们还可以执行以下操作,返回相同的输出:
import 'dart:async';
void main() {
print('Step 1');
myAsyncMethod().then(print);
print('Step 3');
}
Future<String> myAsyncMethod() {
final completer = Completer<String>();
print('Step 2');
Future.delayed(
const Duration(milliseconds: 1),
() => completer.complete('Step 4'),
);
return completer.future;
}