文章目录
Dart 异步任务处理
概述
-
Dart是单线程的
-
Dart是通过事件循环处理任务
-
Dart类库有非常多的返回Future和Stream对象的函数,这些函数称为异步函数,它们只会在设置一些耗时操作之后返回。
Future
- Future表示一个异步任务的最终完成或失败及其结果值得表示,一个Future只会对应一个结果:成功或失败,Future的返回值仍然是一个Future对象。
- Future在执行过程可以划分为两种状态:
- 未完成状态:执行Future内部的任务
- 完成状态:当Future内部的任务执行完成,通常会返回一个值或抛出一个异常
then & catchError & whenComplete
void main(List<String> args) {
print("start");
Future(() {
sleep(Duration(seconds: 2));
print("执行任务");
return "hello";
// throw Exception("发生异常了");
}).then((value) {
print("value: $value");
}).catchError((error) {
print("error: $error");
}).whenComplete(() {
print("执行完毕!!!");
});
print("end");
}
start
end
执行任务
value: hello
执行完毕!!!
Future.value()
直接获取一个完成的Future,会直接调用then函数。
void main(List<String> args) {
print("start");
Future.value("hello").then((value) {
print(value);
});
print("end");
}
start
end
hello
main(List<String> args) {
Future(() {
return "hello";
}).then((value) {
return value + " world";
}).then((value) {
print(value);
});
}
hello world
Future.error()
void main(List<String> args) {
print("start");
Future.error(Exception("这是一个异常")).catchError((error) {
print(error);
});
print("end");
}
start
end
Exception: 这是一个异常
Future.delayed()
延迟执行任务。
void main(List<String> args) {
print("start");
Future.delayed(Duration(seconds: 2), () {
return "hello world";
}).then((value) {
print(value);
});
print("end");
}
start
end
hello world
Future.wait()
等待多个异步任务执行完后进行操作。
void main(List<String> args) {
print("start");
Future.wait([
Future.delayed(Duration(seconds: 2), () {
return "hello";
}),
Future.delayed(Duration(seconds: 3), () {
return "world";
})
]).then((value) {
print("成功:$value");
}).catchError((error) {
print("失败:$error");
});
print("end");
}
start
end
成功:[hello, world]
async/await
async/await
可以实现用同步的代码格式实现异步的调用过程async
用于声明函数,表示这个函数是异步函数await
后面是一个Future,表示会等待异步任务执行完后才会往下走,await必须在async函数内部
基本用法
void main(List<String> args) {
print("start");
getTask().then((value) {
print(value);
});
print("end");
}
Future<String> getTask() async {
print(1);
var result = await Future.delayed(Duration(seconds: 2), () {
return "hello";
});
print(2);
return result + " world";
}
start
1
end
2
hello world
处理地狱回调
举个例子:如现在有个需求是用户先登陆,登陆成功后获取用户id,通过用户id请求接口,获取到用户个人信息后进行数据缓存。
使用Future
void main(List<String> args) {
login("Tom", "666").then((value) {
return getUserInfo(value);
}).then((value) {
saveUserInfo(value);
}).catchError((e) {
print(e);
});
}
Future<String> login(String username, String password) {
print("请求接口:登陆成功");
return Future.value("123456");
}
Future<String> getUserInfo(String id) {
print("请求接口:用户信息");
return Future.value("这是一些用户信息");
}
saveUserInfo(String userInfo) {
print("缓存:$userInfo");
}
请求接口:登陆成功
请求接口:用户信息
缓存这是一些用户信息
使用async/await
void main(List<String> args) {
handleTask();
}
void handleTask() async {
String id = await login("Tom", "666");
String userInfo = await getUserInfo(id);
saveUserInfo(userInfo);
}
Stream
Stream也可以接收异步任务数据,与Future不同的是,它可以接收多个异步任务的结果(成功或失败)。
void main(List<String> args) {
Stream.fromFutures([
Future.delayed(Duration(seconds: 1), () {
return "hello";
}),
Future.delayed(Duration(seconds: 2), () {
throw Exception("异常了");
}),
Future.delayed(Duration(seconds: 3), () {
return "world";
})
]).listen((event) {
print(event);
}, onError: (e) {
print(e.message);
}, onDone: () {
print("onDone");
});
}
hello
e.message
异常了
world
onDone