1. Dart的异步模型
1.1. Dart是单线程的
1.1.1. 如何处理耗时操作
- 处理方式一:多线程,比如Java、OC,开启一个新的线程;
- 处理方式二:单线程+事件循环,比如JavaScript、Dart都是基于单线程加事件循环来完成耗时操作。
1.1.2. 单线程的异步操作
- 阻塞式调用:调用结果返回之前,当前线程会被挂起,调用线程只有在得到调用结果之后才会继续执行;
- 非阻塞师调用:调用执行之后,当前线程不会停止执行,只需要过一段时间来检查一下有没有结果返回即可。
1.2. Dart事件循环
1.2.1 什么是事件循环
单线程模型中主要在维护着一个事件循环(Event loop)。
- 将需要处理的一系列事件(包括点击事件、IO事件、网络事件 )放在一个事件队列(Event Queue)中。
- 不断从事件队列(Event Queue)中取出事件,并执行其对应需要执行的代码块,直到事件队列清空位置。
2. Dart的异步操作
Dart中的异步操作主要使用Future
以及async
、await
。
2.1. 认识Future
2.1.1. 异步的网络请求
main(List<String> args) {
//模拟网络请求
var future = getNetworkData();
//2. 拿到结果 : 因为不知道类型所以用:dynamin, 也可指定类型
future.then ((dynamic value){
print(value);
}).catchError((err){
print(err);
}).whenComplete((){
print ("网络请求结束");
});
}
Future getNetworkData(){
return Future(() {
//1. 将耗时操作包裹到Future的回调函数中
//1.1 只要有返回结果,那么就执行Future对应的then的回调;
//1.2 如果没有结果返回(或请求错误),需要在Future回调中抛出一个异常;
sleep(Duration(seconds: 3));
// throw Exception("网络请求错误");
return "网络请求结果";
});
}
- 只要有返回结果,那么就执行Future对应的then的回调;
- 如果没有结果返回(或请求错误),需要在Future回调中抛出一个异常;
2.1.2 Future的链式调用
场景:第一次网络请求,拿到结果Data1,再以Data1作为参数进行第二次网络请求,拿到结果Data2,再以Data2。。。
Future((){
sleep(Duration(seconds: 3));
return "第一次的结果";
}).then((value) {
print(value);
sleep(Duration(seconds: 3));
return "第二次的结果";
}).then((value) {
print(value);
sleep(Duration(seconds: 3));
return "第三次的结果";
}).then((value) {
print(value);
}).catchError((err) {
});
2.2 await async
- await必须在async函数中才能使用;
- async 函数返回的结果必须是一个Future;
import 'dart:io';
main(List<String> args) {
var result = getNetworkData().then((value) {
print(value);
});
}
/**
* 1. await必须在async函数中才能使用
* 2. async 函数返回的结果必须是一个Future
* */
Future getNetworkData() async {
await sleep(Duration(seconds: 3));
return "网络请求结果"; //内部会将结果自动包裹成一个Future
}
示例:
- 常规Future
void getData() {
getNetworkData("argument1").then((value){
print(value);
return getNetworkData(value);
}).then((value){
print(value);
return getNetworkData(values);
}).then((value) {
print(value);
});
}
Future getNetworkData(String arg) {
return Future((){
sleep(Duration(seconds: 3));
return "Hello word" +arg;
});
}
- awati、async
void getData() async {
var res1 = await getNetworkData("agrument1");
var res2 = await getNetworkData(res1);
var res3 = await getNetworkData(res2);
print(res3);
}
Future getNetworkData(String arg) {
return Future((){
sleep(Duration(seconds: 3));
return "Hello word" +arg;
});
}