微任务异常不会中断事件循环但会终止当前任务,且不跨任务传播;必须用内部try/catch捕获,全局兜底仅用于上报而非恢复。

微任务执行过程中发生的异常不会中断整个事件循环,但也不会自动消失——它会终止当前微任务的后续代码,且若未被显式捕获,将作为“未处理异常”暴露给运行时环境。
微任务异常不跨任务传播
在 Dart 或 JavaScript 中,每个微任务(如 Future.microtask 或 Promise.then 的回调)是独立执行单元。一个微任务内抛出异常,只会影响该任务自身剩余语句的执行,不会波及队列中其他微任务或后续事件任务。
- 例如:连续注册两个微任务,第一个抛出未捕获异常,第二个仍会正常执行
- 这种隔离性源于单线程消息循环的设计,而非错误被“吞掉”,而是被运行时标记为未处理
try/catch 是唯一同步捕获方式
微任务内部的异常必须用 try/catch 显式包裹,否则无法拦截。外部的 try/catch 对已入队的微任务无效——因为微任务是在当前同步代码结束后才执行的。
- 错误写法:
try { Future.microtask(() => throw 'oops'); } catch (e) { ... }—— 捕获不到 - 正确写法:
Future.microtask(() { try { throw 'oops'; } catch (e) { print(e); } });
未捕获异常的兜底出口
当微任务异常未被捕获时,不同平台提供不同级别的兜底机制:
- Dart 中可通过
runZonedGuarded或全局FlutterError.onError捕获 - JavaScript 中触发
unhandledrejection(针对 Promise 微任务)或error事件(极少情况) - 注意:这些兜底不等于“自动恢复”,只是给你上报或记录的机会,异常本身已导致该微任务中断
避免微任务堆积引发异常掩盖
微任务队列优先级高,若大量微任务连续执行,异常可能密集出现;而由于队列无天然分隔,多个未捕获异常可能被压缩成一次日志输出,增加排查难度。
- 建议对关键逻辑的微任务单独加
try/catch,而非依赖全局兜底 - 避免在微任务中执行耗时或易错操作;适合微任务的是轻量、确定性高的逻辑(如状态更新通知)
- 调试时可启用 Dart 的
--enable-asserts或 JS 的devtools > console > preserve log查看逐条异常











