我们首先我来看一张dart的程序启动执行顺序图

从图中我们可以看见当一个dart程序被启动后首先会执行main方法然后会执行eventloop机制,evenloop机制会不停的检查microqueue队列和eventqueue队列,直到我们退出程序。
那么什么是eventloop机制呢?当一个程序被启动后如果没有eventloop循环机制难道程序执行完了就直接退出程序吗?所以event loop 会保活我们的程序并且不停的监听新的任务,例如某一个按钮被点击了又或者是一个文本的输入操作再或者是一个请求等待。
dart的 event loop机制会又两个任务队列及microtaskqueue和eventqueue队列。
1.eventqueue.包含所有外来的事件:I/O,mouse events,drawing events,timers,isolate之间的message等。
Future(() => print('future task'));
Future.delayed(Duration(seconds: 1), () {
print('future task seconds 1');
});
2.microtaskqueue,这个队列我们在实战中很少用,也不推荐用,如果你往里面添加任务会影响dart的正常工作,因为dart程序自身的很多任务都是建立在eventqueue里的,如果你不小心阻塞了他会加班的。。。。
Future.microtask(() => print('Flutter.microtask'));
microtaskqueue里面只要还有task,就需要先执行需要执行microtaskqueue里面的task,直到microtaskqueue里面的任务都执行完了才会继续执行eventqueue里面的任务,eventqueue和microtaskqueue对比的话microtaskqueue更像是老大,老大没只要还没下班我们是走不了的。
3.你真的懂了吗?让我们执行以下代码
void testTask() {
scheduleMicrotask(() => print('microtask 1'));
print('main taks 1');
Future.value(getName('Future.value'))
.then((value) => print('then.${value}'));
Future.microtask(() => print('Flutter.microtask'))
.then((value) => print('Flutter.microtask.then1'));
print('main taks 2');
Future.microtask(() => print('Flutter.microtask2'))
.then((value) => print('Flutter.microtask.then2'));
new Future(() => print('future task'));
}
Future<String> getName(str) async {
print('flutterValueGetName${str}');
return 'flutterValueGetName';
}
我草。。。。你会发现输出竟然是
flutter: main taks 1
flutter: flutterValueGetNameFuture.value
flutter: main taks 2
flutter: microtask 1
flutter: then.flutterValueGetName
flutter: Flutter.microtask
flutter: Flutter.microtask.then1
flutter: Flutter.microtask2
flutter: Flutter.microtask.then2
flutter: future task
惊喜不惊喜意外不意外
我来给大家解释下future.value方法会直接得到一个future值,而then方法会直接被执行。
这里先是输出main taks1 然后会直接输出future.value里面的值,然后再是输出main task 2 ,当main task 2执行完了以后主线任务也就执行完了,
接下来就看microqueue 队列,首先被加入到microqueue队列的是mirotask 1这里执行了后为什么会输出then.flutterValueGetName呢?这是因为之前用future.value封装了一个未来值但是这个未来值由于已经执行完了所以会被插入到microqueue队列中。
接下来输出microtask 和microtask.then1这是因为then后面的方法会直接被执行后面的microtask2和microtask.then2就不用解释了吧。
网友评论