代码执行顺序
下面一段代码的执行顺序是很明显的
int number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
print('${DateTime.now()} $number');
}
顺序输出没有什么问题
flutter: 2021-11-26 19:53:59.727819 start: 1
flutter: 2021-11-26 19:54:02.463404 1000000001
flutter: 2021-11-26 19:54:02.463815 end: 1000000001
async
加上 async
呢?是不是就变成异步的了?
int number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() async {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
print('${DateTime.now()} $number');
}
并没有什么变化,依然按顺序同步执行。
flutter: 2021-11-26 19:57:19.945126 start: 1
flutter: 2021-11-26 19:57:22.676219 1000000001
flutter: 2021-11-26 19:57:22.678135 end: 1000000001
Future
在上文16.第三方库导入与网络数据异步请求与展示中我们的有用到 Future 进行异步网络请求。这里我们模拟网络请求,将耗时操作进行包装:
int number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() {
Future( () {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
print('${DateTime.now()} $number');
});
}
通过打印我们发现这里的确是异步执行的:
flutter: 2021-11-26 20:01:22.301321 start: 1
flutter: 2021-11-26 20:01:22.306180 end: 1
flutter: 2021-11-26 20:01:25.041822 1000000001
Future是什么
通过查看源码我们能够发现。它是一个工厂构造函数。
factory Future(FutureOr<T> computation()) {
_Future<T> result = new _Future<T>();
Timer.run(() {
try {
result._complete(computation());
} catch (e, s) {
_completeWithErrorCallback(result, e, s);
}
});
return result;
}
async - await
思考一下,下面代码的执行顺序会是什么样呢?
nt number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() async {
await Future( () {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
print('${DateTime.now()} $number');
});
print('doSomeThing结束');
}
这里进行一下简单的分析:
在 doSomeThing
内
但 Future
加了 await
,那么在当前作用域中,后面的代码就会被阻塞。
即 print('doSomeThing结束');
这段代码会等待 Future
内的任务完成才执行。
main 函数内
三行代码执行是按顺序执行的,不会受 doSomeThing
内部的 await 的影响
按照预期输出应为:
print('${DateTime.now()} $number');
执行验证✅
flutter: 2021-11-26 20:09:46.105049 start: 1
flutter: 2021-11-26 20:09:46.114976 end: 1
flutter: 2021-11-26 20:09:48.872681 1000000001
flutter: doSomeThing结束
async 和 await 是成对出现的。你也可以试试只写 await,看看是什么效果。
then 与任务的返回值
对 Future
有所了解的话,知道通过 then
我们可以在任务完成的时候进行一些操作。下面对代码嫂做修改:
int number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() async {
await Future( () {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
print('${DateTime.now()} $number');
}).then( (value) {
print('then: ${DateTime.now()} $value');
});
print('doSomeThing结束');
}
输出:
flutter: 2021-11-26 20:20:39.641708 start: 1
flutter: 2021-11-26 20:20:39.649521 end: 1
flutter: 2021-11-26 20:20:42.388725 1000000001
flutter: then: 2021-11-26 20:20:42.390922 null
flutter: doSomeThing结束
这里 then
回调里的 value
是空的,该怎样为 value
赋值呢?很简单,直接在 Future
的任务中 return
就可以了
这里再次修改代码:
int number = 1;
void main() {
print('${DateTime.now()} start: $number');
doSomeThing();
print('${DateTime.now()} end: $number');
}
doSomeThing() async {
await Future( () {
for(int i = 0; i < 1000000000; i++) {
number += 1;
}
return number;
}).then( (value) {
print('then: ${DateTime.now()} $value');
});
print('doSomeThing结束');
}
输出验证✅
flutter: 2021-11-26 20:23:45.843172 start: 1
flutter: 2021-11-26 20:23:45.850300 end: 1
flutter: then: 2021-11-26 20:23:48.584267 1000000001
flutter: doSomeThing结束
符合预期。