Dart的异步
- Future
- async 和 await
- Future相对于async, await的最大优势在于它提供了强大的链式调用
事件循环EventLoop
- Dart EventLoop 有两个列队 :
- 事件列队 Event Queue
- IO
- 手势
- 绘制
- 定时器
- Stream流
- Future
- 微任务列队 MicroTask Queue
- 微任务执行非常短暂
- 通过scheduleMicroTask 调度
- 比事件列队优先级高
- 事件列队 Event Queue
Future
void main(){
print("${DateTime.now().second}开始登录"); //执行
var loginResult = login();
print("${DateTime.now().second}登录已调用"); //执行
//获取异步结果
loginResult.then((value) => print(value));
loginResult.then((value){
print(value);
});
}
Future<String> login(){
return Future((){
print("${DateTime.now().second}登录中..."); //执行
sleep(Duration(seconds:5));
print("${DateTime.now().second}登录成功"); //5s后执行
return "登录成功,即将开启新的宇宙";
});
}
运行结果
1开始登录
1登录已调用
1登录中...
6登录成功
登录成功,即将开启新的宇宙
登录成功,即将开启新的宇宙
- 异步抛出异常 即 执行完成回调
void main() {
login("username", "password")
.then((value) => print(value))
.catchError((error) => print(error))
.whenComplete(() => print("登录结束"));
login("", "password")
.then((value) => print(value))
.catchError((error) => print(error))
.whenComplete(() => print("登录结束"));
login("张三", "password")
.then((value) => print(value))
.catchError((error) => print(error))
.whenComplete(() => print("登录结束"));
}
Future<String> login(String username, String password) {
return Future(() {
print("${DateTime.now().second}登录中..."); //执行
if (username.isEmpty || password.isEmpty) {
throw HttpException("${DateTime.now().second}账号或密码不能为空!");
}
sleep(Duration(seconds: 5));
if (username == "张三"){
throw HttpException("${DateTime.now().second}您已被拉入黑暗深渊!");
}
print("${DateTime.now().second}登录成功"); //5s后执行
return "登录成功,即将开启新的宇宙";
});
}
运行结果
20登录中...
25登录成功
登录成功,即将开启新的宇宙
登录结束
25登录中...
HttpException: 25账号或密码不能为空! //直接抛出异常
登录结束
25登录中...
HttpException: 30您已被拉入黑暗深渊! //5秒后
登录结束
- Future 可以链式调用
登录流程
void main() {
Future.value(["username","password"])
.then((value){
login(value[0],value[1]);
print("${DateTime.now().millisecondsSinceEpoch} >> 登录中...");
sleep(Duration(seconds: 5));
return '{"id": 10001,"name": "John","classGrade": "三年二班","birthday": "2005-12-12 12:12:12", "age": 30}';})
.then((value){
return value;
})
.then((value){
print("${DateTime.now().millisecondsSinceEpoch} >> "+value); //json
var json = jsonDecode(value);
int id = json['id'];
getUserInfo(id);
print("${DateTime.now().millisecondsSinceEpoch} >> 获取用户信息...");
sleep(Duration(seconds: 5));
return "成功,缓存数据,跳转首页";
})
.catchError((value){})
.whenComplete((){
print("登录流程结束!");
});
}
login(String username,String password){
print("${DateTime.now().millisecondsSinceEpoch} >> ${username}请求登录!");
}
getUserInfo(int id){
print("${DateTime.now().millisecondsSinceEpoch} >> ${id}获取用户信息!");
}
结果:
1703559427736 >> username请求登录!
1703559427737 >> 登录中...
1703559432743 >> {"id": 10001,"name": "John","classGrade": "三年二班","birthday": "2005-12-12 12:12:12", "age": 30}
1703559432758 >> 10001获取用户信息!
1703559432758 >> 获取用户信息...
登录流程结束!
Future其他函数
- Future.value Future指定为某个指定值
- Future.error 执行错误回调
- Future.delayed 延时执行
- Future.wait 等待其他异步执行完成后执行
void main() {
print("${DateTime.now().millisecondsSinceEpoch} >> 开始执行");
var future1 = Future.value("aaaaaa").then((value){
sleep(Duration(seconds: 2));//等待2s
print("${DateTime.now().millisecondsSinceEpoch} >> "+value);
});
var future2 = Future.error(HttpException("请求失败!")).catchError((error)=> print(error));
var future3 = Future.delayed(Duration(seconds: 5),(){return "${DateTime.now().millisecondsSinceEpoch} >> 回调函数!";})
.then((value) => print(value)); //5s后输入结果
Future.wait([future2,future1]).then((value) => print("${DateTime.now().millisecondsSinceEpoch} >> 等待 future2 future1 执行完成才执行"));
Future.wait([future1,future2]).then((value) => print("${DateTime.now().millisecondsSinceEpoch} >> 等待 future1 future2执行完成才执行"));
}
执行结果
1703560731843 >> 开始执行
1703560733860 >> aaaaaa //2s后执行 future1
HttpException: 请求失败!
1703560733869 >> 等待 future2 future1 执行完成才执行 //等待future2,future1执行完才执行
1703560733869 >> 等待 future1 future2执行完成才执行 //等待future2,future1执行完才执行
1703560736857 >> 回调函数! // 开始执行后5s才执行 future3 的结果
- Future.doWhile 执行异步操作的循环,打断条件为 不满足return的判断
void main() {
print("开始执行");
var a = 0;
Future.doWhile((){
a++;
print(a);
return a < 5;
});
print("结束执行");
}
结果 看起来好像是主线程阻塞执行
开始执行
1
2
3
4
5
结束执行 加上async
异步执行
void main() {
print("开始执行");
var a = 0;
Future.doWhile(() async {
a++;
print(a);
return a < 5;
});
print("结束执行");
}
结果:
开始执行
1
结束执行
2
3
4
5
- Future.forEach 异步遍历集合
print("开始执行");
Future.forEach(['a','b','c','d','e'], (element){print(element);});
print("结束执行");
开始执行
a
b
c
d
e
结束执行
void main() {
print("开始执行");
Future.forEach(['a','b','c','d','e'], (element) async {print(element);});
print("结束执行");
}
结果:
开始执行
a
结束执行
b
c
d
e
- Future.sync 创建一个同步的Future对象 但是返回的future对象依然是异步的
void main() {
print("开始执行");
Future.sync((){
print("sync");
return "aaa";
}).then((value) => print(value));
print("结束执行");
}
运行结果:
开始执行
sync
结束执行
aaa
- Future.microtask
Future一般会把事件发送到Event Queue中
但是Future.microtask 会把事件加入到Microtask Queue 轻便且速度快的微任务
microtask队列的优先级是比event队列高
void main() {
print("开始执行");
Future((){
print("nomal future");
});
Future.microtask((){
print("microtask future");
});
print("结束执行");
}
结果:
开始执行
结束执行
microtask future
nomal future