首先Dart
是一门单线程的语言,那么Dart
对异步操作
对支持,可以使我们在编写Dart
程序时可以异步的来执行耗时操作。从而可以在等待一个操作完成的同时进行别的操作以下是一些常见的异步操作:
-
通过网络获取数据。
-
写入数据库。
-
从文件读取数据。
要在Dart
中执行异步操作,可以使用Future
类和async
和await
关键字。
# Dart的事件循环(event loop)
在Dart
中,实际上有两种队列:
-
事件队列(
event queue
),包含所有的外来事件:I/O
、mouse events
、drawing events
、timers
、isolate
之间的信息传递。 -
微任务队列(
microtask queue
),表示一个短时间内就会完成的异步任务。它的优先级最高,高于event queue
,只要队列中还有任务,就可以一直霸占着事件循环。microtask queue
添加的任务主要是由Dart
内部产生。
因为
microtask queue
的优先级高于event queue
,所以如果microtask queue
有太多的微任务, 那么就可能会霸占住当前的event loop
。从而对event queue
中的触摸、绘制等外部事件造成阻塞卡顿。
在每一次事件循环中,Dart
总是先去第一个microtask queue
中查询是否有可执行的任务,如果没有,才会处理后续的event queue
的流程。
异步任务我们用的最多的还是优先级更低的 event queue
。Dart
为 event queue
的任务建立提供了一层封装,就是我们在Dart
中经常用到的Future
。
正常情况下,一个 Future
异步任务的执行是相对简单的:
-
声明一个
Future
时,Dart
会将异步任务的函数执行体放入event queue
,然后立即返回,后续的代码继续同步执行。 -
当同步执行的代码执行完毕后,
event queue
会按照加入event queue
的顺序(即声明顺序),依次取出事件,最后同步执行Future
的函数体及后续的操作。
# Future
Future<T>
类,其表示一个 T
类型的异步操作结果。如果异步操作不需要结果,则类型为 Future<void>
。也就是说首先Future
是个泛型类,可以指定类型。如果没有指定相应类型的话,则Future
会在执行动态的推导类型。
# Future基本用法
# Future工厂构造函数
什么是工厂构造函数?
工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象。
在Dart
中,工厂构造函数的关键字为factory
。我们知道,构造函数包含类名构造函数和命名构造方法,在构造方法前加上factory
之后变成了工厂构造函数。也就是说factory
可以放在类名函数之前,也可以放在命名函数之前。
下面我们通过Future
的工厂构造函数,创建一个最简单的Future
。
可以看到,Future
的工厂构造函数接收一个Dart
函数作为参数。这个函数没有参数,返回值是FutureOr<T>
类型。
从打印结果可以看出,Future
不需要结果时,返回的类型是 Future<void>
。
注意,是先执行的类型判断,后打印的Future
内的操作。
# async
和await
默认的Future
是异步运行的。如果想要我们的Future
同步执行,可以通过async
和await
关键字:
可以看到,我们的Future
已经同步执行了。await
会等待Future
执行结束后,才会继续执行后面的代码。
关键字async
和await
是Dart
语言异步支持的一部分。
异步函数即在函数头中包含关键字
async
的函数。