今天我们来学Dart中的异步编程和Future
异步编程

这里我们简单描述一下进程和线程
Future

正常情况下是这样的,这里用了回调函数

void main(List<String> args) {
Future f = Future(() {
return "baka";
throw Exception();//throw抛出异常
});
//then 中接收成功状态
f.then((value) {
print(value);
});
//catchError 中接收失败状态
f.catchError((err) {
print("出~错~了 ! zako~ zako~ zako~");
});
}
异常情况下是这样的

void main(List<String> args) {
Future f = Future(() {
//return "baka";
throw Exception();//throw 抛出异常
});
//then 中接收成功状态
f.then((value) {
print(value);
});
//catchError 中接收失败状态
f.catchError((err) {
print("出~错~了 ! zako~ zako~ zako~");
});
}
Flutter的链式调用
上一个 then 返回对象,会在下一个 then 中接收
void main(List<String> args) {
Future f = Future(() {
return "baka_00";
//throw Exception;
});
//then 中接收成功状态
f
.then((value) {
return Future(() => "baka_01");
})
.then((value) {
return Future(() => "$value----baka_02");
})
.then((value) {
return Future(() => "$value----baka_03");
})
.then((value) {
print(value);
})
.catchError((err) {
print("出~错~了 ! zako~ zako~ zako~");
});
}
void main() {
Future.value(10)
.then((value) {
print("第1步收到:$value");
// 返回一个新值(会传给下一个 then)
return value + 5;
})
.then((value) {
print("第2步收到:$value");
// 再返回一个值
return value * 2;
})
.then((value) {
print("第3步收到:$value");
})
.catchError((error) {
print("发生错误:$error");
});
}
async和await

你可以发现在函数的参数括号后面有async 指的是 asynchronous(异步),代表当前函数是异步的
| 关键字 | 作用 |
|---|---|
| async | 声明函数是异步 |
| await | 等待异步结果 |
Future<String> getName() async {
return "Tom";
}
void main() async {
var name = await getName();
print(name);
}
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2)); //延迟两秒钟,和unity中的协程非常相似
return "数据加载完成";
}
void main() async {
print("开始请求");
var data = await fetchData();
print(data);
print("结束");
}
这里你可以注意到一行代码 Future.delayed(Duration(seconds: 2));
这里其实完整格式是
(new) Future<String>.delayed(Duration duration, [FutureOr<String> Function()? computation])
其中第一个参数Duration duration是指延迟时间例如延迟一秒钟Duration(seconds: 1)
而第二个参数是可选的,即延迟时间之后的返回值,通常为 匿名函数()=>{ return 返回值 },这里的返回值必须和泛型里规定的一致
Future<String> getUser() async {
return Future.delayed(Duration(seconds: 1), () {
return "Tom";
});
}
Future<String> getOrder(String user) async {
return Future.delayed(Duration(seconds: 1), () {
return "$user 的订单:iPhone";
});
}
Future<String> getDetail(String order) async {
return Future.delayed(Duration(seconds: 1), () {
return "$order(128GB)";
});
}
void main() async {
print("开始请求");
var user = await getUser();
print("用户:$user");
var order = await getOrder(user);
print("订单:$order");
var detail = await getDetail(order);
print("详情:$detail");
print("结束");
}
try catch
这个和C#里的很像,C#里也有try catch函数,这里 try 指的是 尝试(try block) 而catch指的是 捕获(catch exception)
void main() {
try {
int a = 10 ~/ 0; // 整数除零,会报错
print(a);
} catch (e) {
print("出错了:$e");
}
}
在异步里就是
Future<String> getData() async {
throw Exception("网络挂了");
}
void main() async {
try {
var data = await getData();
print(data);
} catch (e) {
print("捕获到错误:$e");
}
}
其实和if lese的逻辑差不多,只不过这个是应对错误情况使用的
on关键字
这个其实在之前我们学mixin的时候就遇到了,不过on关键字在不同场景下的作用不太一样
在try on中
我们刚才说的try catch的catch的参数是error,也就是接受一切错误并反馈
但是这里try on 就不是了
在这里 on = 只捕获某种指定类型的异常
try {
...
}
on 异常类型 {
...
}
例如刚才的这个例子返回值是 IntegerDivisionByZeroException

而我们只提取这一个问题并输出就行了
void main() {
try {
int a = 10 ~/ 0; // 整数除零,会报错
print(a);
} on IntegerDivisionByZeroException {
print("不能除0");
}
}

甚至还能这样玩
void main() {
try {
//List越界
List list = [1, 2];
print(list[5]);
}on RangeError {
print("越界");
}
try {
// 整数除0
int a = 10 ~/ 0;
} on IntegerDivisionByZeroException {
print("除零");
}
try {
// 格式错误
int.parse("abc");
} on FormatException {
print("格式错误");
}
}
在mixin中
在mixin中我们知道with关键字可以让类使用mixin里的参数和方法
而我们在mixin中使用on就是限制只有哪些类可以使用这个mixin
class Animal {
//所有的动物都会吃东西
void eat() {
print("动物吃东西");
}
}
//鸟继承动物类
class Bird extends Animal {
void layEgg() {
print("鸟下蛋");
}
}
//猫继承动物类
class Cat extends Animal {}
//狗继承动物类
class Dog extends Animal {}
//但是飞行和下蛋能力我只允许鸟可以
mixin Fly on Bird {
void fly() {
eat();
layEgg();
print("鸟在飞");
}
}
//这样麻雀类继承鸟类就可以飞了
class Sparrow extends Bird with Fly {}
void main() {
Sparrow s = Sparrow();
s.fly();
}




评论区