787 字
4 分钟
异步编程之Future
代码执行顺序
下面一段代码的执行顺序是很明显的
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: 1flutter: 2021-11-26 19:54:02.463404 1000000001flutter: 2021-11-26 19:54:02.463815 end: 1000000001async
加上 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: 1flutter: 2021-11-26 19:57:22.676219 1000000001flutter: 2021-11-26 19:57:22.678135 end: 1000000001Future
在上文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: 1flutter: 2021-11-26 20:01:22.306180 end: 1flutter: 2021-11-26 20:01:25.041822 1000000001Future是什么
通过查看源码我们能够发现。它是一个工厂构造函数。
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是异步执行的- 但
Future加了await,那么在当前作用域中,后面的代码就会被阻塞。- 即
print('doSomeThing结束');这段代码会等待Future内的任务完成才执行。
- 即
- main 函数内
- 三行代码执行是按顺序执行的,不会受
doSomeThing内部的 await 的影响
- 三行代码执行是按顺序执行的,不会受
- 按照预期输出应为:
- start
- end
print('${DateTime.now()} $number');- doSomeThing结束
执行验证✅
flutter: 2021-11-26 20:09:46.105049 start: 1flutter: 2021-11-26 20:09:46.114976 end: 1flutter: 2021-11-26 20:09:48.872681 1000000001flutter: 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: 1flutter: 2021-11-26 20:20:39.649521 end: 1flutter: 2021-11-26 20:20:42.388725 1000000001flutter: then: 2021-11-26 20:20:42.390922 nullflutter: 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: 1flutter: 2021-11-26 20:23:45.850300 end: 1flutter: then: 2021-11-26 20:23:48.584267 1000000001flutter: doSomeThing结束符合预期。