You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中Future.value与Future.microtask的差异及执行顺序解析

Dart中Future.value与Future.microtask的行为差异解析

先看两个测试案例及输出:

Case 1

Future.microtask(() => 1).then(print);
Future.microtask(() => Future(() => 2)).then(print);
Future.value(3).then(print);
Future.value(Future(() => 4)).then(print);

输出:

1
3
4
2

Case 2(调换语句顺序)

Future.value(3).then(print);
Future.value(Future(() => 4)).then(print);
Future.microtask(() => 1).then(print);
Future.microtask(() => Future(() => 2)).then(print);

输出:

3
1
4
2

针对这两个案例,下面逐一解答问题:

1. Future.value与Future.microtask的区别是什么?

  • Future.value:
    • 如果传入非Future类型的值,会立即将该值作为Future的完成结果,同时把后续的then回调加入微任务队列等待执行。
    • 如果传入的是Future对象,则会等待这个传入的Future完成,之后再将then回调放入对应队列(取决于传入的Future完成时所在的队列)。
  • Future.microtask:
    • 会把传入的回调函数直接加入微任务队列,等微任务队列被处理时执行该回调。
    • 回调的返回值会作为这个Future的结果;如果回调返回的是Future对象,当前Future会等待这个返回的Future完成,再触发后续的then回调。

2. 两者谁的优先级更高,谁会先完成?

Dart的任务队列分为微任务队列(优先级更高)和事件队列(优先级更低),只有微任务队列的所有任务处理完毕后,才会处理事件队列的任务。

Future.value(传入非Future值)和Future.microtask的任务都属于微任务队列,优先级完全相同,执行顺序只取决于被加入微任务队列的先后:

  • Case1中先调用Future.microtask(() => 1),再调用Future.value(3),所以先输出1,再输出3。
  • Case2中先调用Future.value(3),再调用Future.microtask(() => 1),所以先输出3,再输出1。

3. 为何最终输出中4和2的顺序始终保持不变?

拆解两者的执行逻辑:

  • 输出4的逻辑:Future.value(Future(() => 4))里的Future(() => 4)是普通Future,它的回调会被直接加入事件队列。当这个事件任务执行完毕后,才会触发外层Future.value的then(print)输出4。
  • 输出2的逻辑:Future.microtask(() => Future(() => 2))会先把回调加入微任务队列;等微任务处理到这个回调时,才会创建Future(() => 2)并将其回调加入事件队列。当这个事件任务执行完毕后,才会触发外层Future.microtask的then(print)输出2。

不管案例中语句顺序如何调换:

  • Future(() => 4)总是比Future(() => 2)更早进入事件队列:Case1中前者会立即创建事件任务,后者要等微任务执行时才创建;Case2中前者先被调用,更早创建事件任务。
  • 事件队列按任务加入顺序执行,所以Future(() => 4)的任务总是先完成,输出4,之后才是Future(() => 2)的任务完成输出2,因此两者顺序始终不变。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:00:56