async
任何一个GUI开发者都明白一个朴素的道理-"不能在UI线程中进行耗时的操作"
为此,我们总是在学习任何一门前端架构的时候,总会不自觉的首先去思考,该语言或者框架是如何进行异步操作的,诸如网络操作,IO操作等,而进行异步操作之后,我们如何拿到数据,或者又怎么解决并发问题,这都是一门前端语言基本的元素。
flutter中,通俗的讲,其线程模型是单线程的,我们无需进行线程的申明,并管理其并发状态,这一点要比java开发简单许多。
但这只是一种方便开发者的机制,开发者并不能违背基本的原则,也就是不能直接执行一个阻塞操作,我们还是需要将耗时操作进行异步申明。
在Dart中,我们在可以方法中申明 sync关键字 来表示这是一个异步方法。伪代码如下
getDate() async {
delayed(5).callback(
print("test2")
)
}
getDate();
print("test1")
在方法后面加上sync关键字 此时 该函数将不会阻塞 打印结果为 test1然后5秒之后打印test2
这是一个很简单的例子,但也确实是Dart中大部分异步方法的书写方式,剩下的所有操作,都将以async为基础
*await
有时候,我们需要依靠异步结果的返回,来进行某些操作,比如嵌套的网络请求,在获取第一个结果之后进行第二次操作,伪代码如下。
getData() async{
delayedTask(5).callback(value){
getData2();
}
}
这只是两层的嵌套使用而已,在回调中嵌套一个另一个异步操作,但是如果嵌套的多了呢?
getData() async{
await delayedTask(5).callback(data1){
getData2(data1).callback(data2){
getData3(data2).callback(data3){
.....
}
}
}
}
实际的代码将比这更加复杂,我们陷入了回调地狱。
为了避免这种情况,Dart提供了 await 关键字,顾名思义,等待,等待一个异步操作的完成。
我们将代码修改一下
getData() async{
var result1 = await delayedTak(5)
var result2 = await getData2(result1);
......
}
在异步代码块之前设置 await关键字 表示等待这个任务完成在进行下一段代码执行。
必须要注意 await关键字必须在 async函数中调用,编辑器将提示这一点。
await的另一点需要注意的是,调用await的地方 也必须是await的 否则 await关键字将无效,代码依旧是异步执行。 既然我等待了,那你也必须等待。像极了等女朋友化妆的你。
getData() async{
var result1 = await delayedTak(5)
var result2 = await getData2(result1);
......
}
main() async{
await getData();
}
使用 await关键字可以避免回调地狱。
future
我们已经知道如何标记一个函数是async函数,但事实上,我们必须得实际创建一段异步操作,就如同java中,new一个Thread()之后 还需要放一个Runable()
Dart中,我们使用future来表明一段异步任务,future的意思是未来,也就是未来会发生的事儿。
上面的代码 实际上应该这样写
Future<String> getData() async{
return Future.delayed(const Duration(seconds: 5), () => "test");
}
main() {
var Future<String> result = getData();
}
当你的函数加入 async之后 函数返参就固定为Future了
我们在main方法中得到这个future函数
此时异步代码并没有真正的执行,他们还处在未来的某一刻,我们需要开始观察这个future,他才会开始工作
Future<String> getData() async{
return Future.delayed(const Duration(seconds: 5), task => "test");
}
main() {
var Future<String> future = getData();
future.then(result){
print(result)
}
}
调用future的then方法来获取task返回的数据,这其实就是观察者模式的一种实现。
当然 结合我们上面讲的 当我们将future前面加入 await的话 我们就可以直接拿到返回数据了
Future<String> getData() async{
return Future.delayed(const Duration(seconds: 5), task => "test");
}
main() async{
var result = await getData();
print(reslut)
}
打印结果同样是"test"
async await 和future 这几乎是Dart里异步的基本操作方法了。
下次我们来讲如何在widget树中对future进行监听,以及如何转换future
网友评论