如下内容从官网获得:
https://webdev.dartlang.org/articles/performance/event-loopjavascript
Even-Looper
Dart是单线程模型,也就没有了所谓的主线程/子线程之分。
Dart也是Event-Looper以及Event-Queue的模型,全部的事件都是经过EventLooper的依次执行。html
而Dart的Event Loop就是:java
- 从EventQueue中获取Event
- 处理Event
- 直到EventQueue为空

而这些Event包括了用户输入,点击,Timer,文件IO等web

单线程模型
一旦某个Dart的函数开始执行,它将执行到这个函数结束,也就是Dart的函数不会被其余Dart代码打断。api
Dart中没有线程的概念,只有isolate,每一个isolate都是隔离的,并不会共享内存。而一个Dart程序是在Main isolate的main函数开始,而在Main函数结束后,Main isolate线程开始一个一个(one by one)的开始处理Event Queue中的每个Event。异步

Event Queue以及Microtask Queue
Dart中的Main Isolate只有一个Event Looper,可是存在两个Event Queue:Event Queue以及Microtask Queueasync
Microtask Queue存在的意义是:
但愿经过这个Queue来处理稍晚一些的事情,可是在下一个消息到来以前须要处理完的事情。函数
当Event Looper正在处理Microtask Queue中的Event时候,Event Queue中的Event就中止了处理了,此时App不能绘制任何图形,不能处理任何鼠标点击,不能处理文件IO等等oop
Event-Looper挑选Task的执行顺序为:post
- 优先所有执行完Microtask Queue中的Event
- 直到Microtask Queue为空时,才会执行Event Queue中的Event

Dart中只能知道Event处理的前后顺序,可是并不知道某个Event执行的具体时间点,由于它的处理模型是一个单线程循环,而不是基于时钟调度(即它的执行只是按照Event处理完,就开始循环下一个Event,而与Java中的Thread调度不同,没有时间调度的概念),也就是咱们既是指定另外一个Delay Time的Task,但愿它在预期的时间后开始执行,它有可能不会在那个时间执行,须要看是否前面的Event是否已经Dequeue。
异步任务调度
当有代码能够在后续任务执行的时候,有两种方式,经过dart:async这个Lib中的API便可:
- 使用Future类,能够将任务加入到Event Queue的队尾
- 使用scheduleMicrotask函数,将任务加入到Microtask Queue队尾
当使用EventQueue时,须要考虑清楚,尽可能避免microtask queue过于庞大,不然会阻塞其余事件的处理

使用Future
通常经常使用的Future构造函数:
new Future((){ // doing something });
而通常经常使用的还有当有分治任务时,须要将一个大任务拆成不少小任务一步步执行时,就须要使用到Future.then函数来拆解任务
void main(){ new Future(() => futureTask) // 异步任务的函数 .then((m) => "futueTask execute result:$m") // 任务执行完后的子任务 .then((m) => m.length) // 其中m为上个任务执行完后的返回的结果 .then((m) => printLength(m)) .whenComplete(() => whenTaskCompelete); // 当全部任务完成后的回调函数 } int futureTask() { return 21; } void printLength(int length) { print("Text Length:$length"); } void whenTaskCompelete() { print("Task Complete"); }
当任务须要延迟执行时,能够使用new Future.delay来将任务延迟执行,而如上所述,只有当Main isolate的Event Queue处于Idle的状态时,才会延迟1s执行,不然等待的时间会比1s长不少
new Future.delayed(const Duration(seconds: 1), () => futureTask);
当须要作动画的时候,不要使用Future,而须要使用animateFrame
PS:
- Future中的then并无建立新的Event丢到Event Queue中,而只是一个普通的Function Call,在FutureTask执行完后,当即开始执行
- 当Future在then函数先已经执行完成了,则会建立一个task,将该task的添加到microtask queue中,而且该任务将会执行经过then传入的函数
- Future只是建立了一个Event,将Event插入到了Event Queue的队尾
- 使用Future.value构造函数的时候,就会和第二条同样,建立Task丢到microtask Queue中执行then传入的函数
- Future.sync构造函数执行了它传入的函数以后,也会当即建立Task丢到microtask Queue中执行
使用scheduleMicrotask
在最顶层的调用关系中,使用该函数便可
async.scheduleMicrotask(() => microtask()); void microtask(){ // doing something }
使用isolate以及Worker
当有计算很繁重的任务时,则须要使用isolate或者Worker来执行,以保持App对用户操做的及时响应。Isolate的实现多是一个单独的线程,或者一个单独的进程,须要看Dart VM是如何实现的。