Dart是单线程模型的,通过isolate也可以实现对多核的利用

EventLoop

Dart一次只能执行一个操作,然后一个接一个,只有要操作正在执行,他就不会被其它任何操作中断。

组成

Dart的EventLoop事件循环和JavaScript类似,同样循环中有两个FIFO队列:一个是事件队列(Event Queue),另一个是微任务队列(MicroTask Queue)。

Event Queue

主要包含一些外部事件和Future,比如IO,绘制,手势以及Timer等

MicroTask Queue

主要用于Dart内部的微任务,一般是通过 scheduleMicroTask方法实现调度,这些任务需要在其它内部微任务执行完成之后且把事件移交给时间队列之前异步执行。

执行流程

Dart应用程序启动时,创建一个新的Thread(在Dart中专业叫isolate),这个线程是整个应用的主线程。当这个线程被创建,Dart就会自动执行以下几步:

  • 初始化两个队列,分别是事件队列和微任务队列
  • 执行main方法
  • 启动事件循环EventLoop

Future

Future可以简单理解,是一个盲盒,对于一些特殊的任务需要异步执行时,那么就是把这个任务打包到盲盒里面去。当这些任务执行就绪,再进行开盲盒。

Future 状态

  • 未完成:Uncompleted
  • 正常完成: Completed
  • 异常完成: Completed with error

基本使用

1. 构造函数创建

factory Future(FutureOr computation())

2. 创建一个带有返回值的Future

  1. var valueFuture = Future.value(100.0);

3. 创建一个延迟执行的future

  1. Future.delayed(Duration(seconds: 3), () => print('this is delayed future'));

4.Future的foreach

forEach 就是根据某个集合,创建一系列的Future方法,然后按照创建的顺序执行

  1. void main() {
  2. var futureList = Future.forEach([1,2,3,4,5], (element) {
  3. print(element);
  4. });
  5. }

5. Future的any

any方法和forEach不同,它只返回第一个执行完成的future结果,不管是正常返回还是返回一个error。

6. Future的dowhile

Future.doWhile方法就是重复性地执行某一个动作,直到返回false或者Future.

7. Future的wait

用来等待多个future完成,并整合他们的结果:

  • 所有的feture正常结果返回:则future的返回结果是所有future的结果的集合
  • 若其中一个future有error返回:则future的返回结果是第一个error的值
  1. void main() {
  2. var request1 = Future.delayed(Duration(seconds: 3), () => 1534);
  3. var request2 = Future.delayed(Duration(seconds: 2), () => 23);
  4. var request3 = Future.delayed(Duration(seconds: 2), () => 3);
  5. Future f = Future.wait({request1, request2, request3}).then((List<int> value) => {
  6. print('${value.reduce((value, element) => value + element)}')
  7. });
  8. }

8. Future的microtask

Future.microtask 提供了一种将事件加入到MicroTask Queue,创建一个高优先级的Future。

9. Future的sync

Future.sync方法返回的是一个同步的Future,但如果这个Future使用then注册,那会把这个Future加入到MicroTask Queue中。

  1. void main() {
  2. Future.sync(() => print('sync future')).then((value) => print('sync then'));
  3. print('main is end');
  4. }
  5. >>>
  6. sync future
  7. main is end

Future 返回结果

1. Future.then

  • 注册Future的回调,返回的还是Future

2. Future.catchError

  • 注册一个回调,处理有异常Future
  1. The `Function` below stands for one of two types:
  2. - (dynamic) -> FutureOr<T>
  3. - (dynamic, StackTrace) -> FutureOr<T>

3. Future.whenComplete

Future.whenComplete方法有点类似异常捕获中的try-catch-finally中的finally, 一个Future不管是正常回调了结果还是抛出了异常最终都会回调 whenComplete 方法。

一些用法

处理Future返回的结果

  • 处理一般异步场景都能用,特别是处理多个Future的问题,包括前后依赖,聚合多个Future
  • 单个场景可以使用async和await
  • Future处理轻量级异步,对于比较耗时的任务,还是需要开启isolate

async & await

  • 本质上是Future的另一种封装
  • 同步化的结构代码完成异步业务
  • await关键字必须配合async关键字一起使用
  • 异常的处理使用try catch完成
  • async修饰的方法返回的是一个Future对象

引用