Future 详解
Future类是对未来结果的一个代理,它返回的并不是被调用的任务的返回值。
void myTask(){
print("this is my task");
}
void main() {
Future fut = new Future(myTask);
}
如上代码,Future类实例fut并不是函数myTask的返回值,它只是代理了myTask函数,封装了该任务的执行状态。
创建 Future
Future的几种创建方法
Future()Future.microtask()Future.sync()Future.value()Future.delayed()Future.error()
其中sync是同步方法,任务会被立即执行
import 'dart:async';
void main() {
print("main start");
new Future.sync((){
print("sync task");
});
new Future((){
print("async task");
});
print("main stop");
}
运行结果:
main start
sync task
main stop
async task
注册回调
当Future中的任务完成后,我们往往需要一个回调,这个回调立即执行,不会被添加到事件队列。
import 'dart:async';
void main() {
print("main start");
Future fut =new Future.value(18);
// 使用then注册回调
fut.then((res){
print(res);
});
// 链式调用,可以跟多个then,注册多个回调
new Future((){
print("async task");
}).then((res){
print("async task complete");
}).then((res){
print("async task after");
});
print("main stop");
}
运行结果:
main start
main stop
18
async task
async task complete
async task after
除了then方法,还可以使用catchError来处理异常,如下
new Future((){
print("async task");
}).then((res){
print("async task complete");
}).catchError((e){
print(e);
});
还可以使用静态方法wait 等待多个任务全部完成后回调。
import 'dart:async';
void main() {
print("main start");
Future task1 = new Future((){
print("task 1");
return 1;
});
Future task2 = new Future((){
print("task 2");
return 2;
});
Future task3 = new Future((){
print("task 3");
return 3;
});
Future fut = Future.wait([task1, task2, task3]);
fut.then((responses){
print(responses);
});
print("main stop");
}
运行结果:
main start
main stop
task 1
task 2
task 3
[1, 2, 3]
如上,wait返回一个新的Future,当添加的所有Future完成时,在新的Future注册的回调将被执行。
async 和 await
在Dart1.9中加入了async和await关键字,有了这两个关键字,我们可以更简洁的编写异步代码,而不需要调用Future相关的API
将 async 关键字作为方法声明的后缀时,具有如下意义
- 被修饰的方法会将一个
Future对象作为返回值 - 该方法会同步执行其中的方法的代码直到第一个 await 关键字,然后它暂停该方法其他部分的执行;
- 一旦由 await 关键字引用的 Future 任务执行完成,await的下一行代码将立即执行。
// 导入io库,调用sleep函数
import 'dart:io';
// 模拟耗时操作,调用sleep函数睡眠2秒
doTask() async{
await sleep(const Duration(seconds:2));
return "Ok";
}
// 定义一个函数用于包装
test() async {
var r = await doTask();
print(r);
}
void main(){
print("main start");
test();
print("main end");
}
运行结果:
main start
main end
Ok
需要注意,async 不是并行执行,它是遵循Dart 事件循环规则来执行的,它仅仅是一个语法糖,简化Future API的使用。
参考资料: Dart 文档
公众号“编程之路从0到1”