bloc.add() 不是你以为的那样
来源:dev.to — 2026-10-25
📋 概述
Flutter 老手看到 BlocSignal 的示例代码里写着 surfaceBloc.add(UpdateFormField(...)),肌肉记忆立刻发问:这不是把事件丢进 StreamController 的 sink、在 Dart 事件循环上排一个微任务、切断调用栈、等下一帧才更新界面吗?作者的答案是:在 BlocSignal 里 .add() 是同步派发的。当事件处理器和它的转换器都同步执行时,从派发到发射的整条管线在同一条调用栈上内联跑完,耗时 0ms。等到 add() 下一行执行时,底层 DataModel 的信号单元已经更新,界面上所有绑定和校验规则已经重算,value 已经持有新的不可变状态快照。文章的论点是经典 bloc 的异步微任务税在生成式界面里不可接受:一旦 AI 代理的界面落在客户端,每一次按键、每条校验规则、每个叶子节点重建都必须在同步信号图上以 0ms 完成,而异步网络流应该只留在架构外围。
🔑 核心要点
- BlocSignal 的 .add() 在当条调用栈上同步派发,不是排到事件循环的微任务
- 等 add() 的下一行执行时,数据模型、所有绑定与校验、状态快照都已经更新完毕
- 经典 bloc 通过 StreamController 传导事件,即使处理器不做异步工作也要跨微任务边界
- 作者的边界原则:异步网络流留在外围,客户端每一次按键和重建必须 0ms 完成
💡 金句
“When an event handler and its transformer execute synchronously, the entire dispatch-to-emission pipeline runs inline on the exact same call stack in 0ms.”
译:当事件处理器及其转换器同步执行时,从派发到发射的整条管线都会在同一条调用栈上内联跑完,耗时 0 毫秒。
← 返回 dev.to 首页