flutter 哪些任务是在微队列,哪些是在事件队列

Flutter 异步机制:微任务队列 vs 事件队列

在 Dart/Flutter 的事件循环(Event Loop)中,任务队列分为两个优先级:微任务队列(Microtask Queue)事件队列(Event Queue)

核心原则是:微任务队列优先级 > 事件队列 。 每次执行完一段同步代码后,Dart 会先清空微任务队列中的所有 任务,然后再去事件队列取一个任务执行。

以下是具体的分类:

1. 微任务队列 (Microtask Queue)

这里面的任务非常"急",通常用于内部状态的更新,或者希望在下一次 UI 渲染或 IO 操作前立即执行的代码。

  • scheduleMicrotask(): dart:async 库中直接调度微任务的方法。
  • Future.microtask(): 创建一个旨在微任务中运行的 Future。
  • Future.then() / .catchError() / .whenComplete() 的回调:
    • 当一个 Future 完成(complete)时,它的后续回调方法会被加入微任务队列。
    • 注意 :如果是 Future.value() 这种立即完成的 Future,它的 .then 也会立刻进入微任务队列。
  • async/await 的恢复执行:
    • await 等待的 Future 完成后,async 函数体内的后续代码(恢复执行部分)实际上被视为微任务调度。

2. 事件队列 (Event Queue)

这里主要包含外部事件、I/O 和定时器,是大部分异步任务发生的地方。

  • I/O 事件: 文件读写完成、网络请求返回数据等。
  • 定时器 : Future.delayed()Timer.run()Timer.periodic()
    • 注意Future.delayed 即使延时为 0,也是进入事件队列,因此它肯定比微任务晚执行。
  • Future() 构造函数 :
    • 例如 Future(() { ... }),这种普通的构造函数会将任务放入事件队列。
  • UI / 手势事件: 点击、滑动、键盘输入等(由 Engine 层传递给 Framework)。
  • 绘制指令: VSync 信号到来时触发的绘制任务。
  • Isolate 消息 : 其他 Isolate 发送到 ReceivePort 的消息。

简单对比总结

任务来源 队列归属 优先级
scheduleMicrotask(...) Microtask 高 (插队执行)
Future.microtask(...) Microtask
Future.then(...) Microtask
Future.value(...).then Microtask
Timer.run(...) Event 低 (排队执行)
Future.delayed(...) Event
Future(() => ...) Event
点击、IO、网络 Event

避坑指南

⚠️ 风险提示 :如果在微任务队列中无限循环添加微任务(例如递归调用 scheduleMicrotask),那么事件队列永远没有机会执行。 会导致:

  1. App 界面卡死(因为 UI 绘制事件在事件队列)。
  2. 点击无反应(手势事件在事件队列)。
  3. 网络请求不回调(IO 事件在事件队列)。

代码示例

dart 复制代码
import 'dart:async'; // 必须导入这个库

void main() {
  print('1. 同步代码开始');

  // 事件队列
  Future(() => print('6. Future() 去事件队列'));
  Future.delayed(Duration.zero, () => print('7. Future.delayed 去事件队列'));

  // 微任务队列
  scheduleMicrotask(() => print('3. scheduleMicrotask 去微任务队列'));
  Future.microtask(() => print('4. Future.microtask 去微任务队列'));
  
  // Future.value 是立即完成,.then 进入微任务
  Future.value().then((_) => print('5. Future.value().then 去微任务队列'));

  print('2. 同步代码结束');
}

打印结果:

相关推荐
stringwu2 天前
Flutter 开发必备:MVI 架构的高效实现指南
前端·flutter
程序员老刘3 天前
Flutter版本选择指南:3.44系列继续观望 | 2026年6月
flutter·ai编程·客户端
用户965597361904 天前
Provider vs Bloc vs GetX vs Riverpod:Flutter 状态管理方案怎么选?
flutter
恋猫de小郭4 天前
Flutter Patchwork,不用 Fork 改依赖包源码的第三方工具
android·前端·flutter
程序员老刘5 天前
跑分第一的编程大模型,我为啥不用?
flutter·ai编程·vibecoding
恋猫de小郭5 天前
苹果 AirPods 协议,Android 也可以使用完整版 AirPods 能力
android·前端·flutter
张风捷特烈5 天前
Flutter 类库大揭秘#01 | path_provider架构与设计
android·flutter
恋猫de小郭8 天前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
恋猫de小郭8 天前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
程序员老刘10 天前
跨平台开发地图 | 2026年6月
flutter·ai编程·客户端