Future , async/await 表示异步任务
一个Dart应用有一个消息循环和两个消息队列-- event队列和microtask队列
event队列包含所有外来的事件:I/O,mouse events,drawing events,timers,isolate之间的message等。
microtask 队列在Dart中是必要的,因为有时候事件处理想要在稍后完成一些任务但又希望是在执行下一个事件消息之前。
所以执行顺序是:
main() -> microtask 队列(插队) -> event 队列
microtask中消息执行完毕之后,才会执行event队列中的消息
Future 会在event队列的末尾添加一个事件消息
then会在Future事件执行完成之后立即执行某段代码(这段代码没有被添加到消息队列中,只是被回调了),可以用来表明几个实现之间明确的依赖关系
实践:
import 'dart:async';
main() {
print('main #1 of 2');
scheduleMicrotask(() => print('microtask #1 of 3'));
new Future.delayed(new Duration(seconds:1), () => print('future #1 (delayed)'));
new Future(() => print('future #2 of 4'))
.then((_) => print('future #2a'))
.then((_) {
print('future #2b');
scheduleMicrotask(() => print('microtask #0 (from future #2b)')); })
.then((_) => print('future #2c'));
scheduleMicrotask(() => print('microtask #2 of 3'));
new Future(() => print('future #3 of 4'))
.then((_) => new Future( () => print('future #3a (a new future)')))
.then((_) => print('future #3b'));
new Future(() => print('future #4 of 4'));
scheduleMicrotask(() => print('microtask #3 of 3'));
print('main #2 of 2'); }
答案:
main #1 of 2
main #2 of 2
microtask #1 of 3
microtask #2 of 3
microtask #3 of 3
future #2 of 4
future #2a
future #2b
future #2c
microtask #0 (from future #2b)
future #3 of 4
future #4 of 4
future #3a (a new future)
future #3b
future #1 (delayed)
个人理解:
1.main()方法里面的同步方法首先执行,打印
main #1 of 2
main #2 of 2
2.Futurn 消息被添加到event队列,microtask 消息(scheduleMicrotask)被添加到microtash队列,microtask 队列优先于event队列执行,microtask 队列按顺序执行打印
microtask #1 of 3
microtask #2 of 3
microtask #3 of 3
3.Future异步消息根据event队列中的顺序开始执行,future #2 of 4 优先于future #3 of 4 ,future #4 of 4 ,future #2 of 4 执行过程中根据then的依赖关系顺序执行,在第三步then中又创建了一个microtask的异步消息,microtask队列不影响event队列中的执行,此时then中回调因为future #2 of 4 消息执行完而被同步调起,所以会在回调执行完之后,将microtask消息插入执行(此时插队),打印
future #2 of 4
future #2a
future #2b
future #2c
microtask #0 (from future #2b)
4.Future 中 future #3 of 4 的回调本该顺序执行,但是第二步中产生了一个异步的新的Future,这个Future被放入到event队列的尾部,而第三步依赖于第二步,导致future #4 of 4优先于future #3 of 4中的第二个回调被执行,打印
future #3 of 4
future #4 of 4
future #3a (a new future)
future #3b
5.Future.delayed 延时一秒将Future放入event队列,无疑此Future在队列的末尾,所以最后打印