节流应放在 emit 前或事件消费端,而非总线内部;它用于防高频事件冲击,需按业务独立配置,且不可用于生命周期类事件。

节流在微前端通信总线中不是用来“限制广播频率”的工具,而是防止高频事件(如 resize、scroll、input)触发过多 emit 调用,避免总线被瞬时消息洪峰冲击。它作用于消息发起端,而非总线本身或接收方。
为什么节流要放在 emit 前,而不是总线内部
总线本质是中转层,职责是可靠分发,不应承担业务节奏控制。若把节流逻辑塞进 bus.emit,会导致:
- 所有事件共用同一时间窗口,登录成功和搜索输入被强制“绑死”节流
- 不同子应用对同一事件的节流策略无法独立配置(比如订单页需 500ms,监控页需 2s)
- 破坏 request-response 的时效性——节流 delay 会拖慢响应 Promise 的 resolve 时间
在子应用中对特定事件做节流封装
推荐在子应用触发方主动封装,保持总线纯净。例如用户实时搜索场景:
// 子应用内:对搜索关键词变更做节流
import { throttle } from 'lodash'; // 或用原生实现
const throttledSearchEmit = throttle((keyword) => {
bus.emit('search:input', { keyword, timestamp: Date.now() });
}, 300);
// 绑定到 input 事件
inputElement.addEventListener('input', (e) => {
throttledSearchEmit(e.target.value);
});
这样既不侵入总线,又确保每 300ms 最多广播一次,且不影响其他事件(如 'user:logout')立即发出。
主应用侧对广播类事件做节流消费
当主应用需响应高频广播(如子应用持续上报位置),可在监听端节流处理,避免 UI 频繁重绘:
// 主应用:只在每 1s 内最后一次位置更新时刷新地图
const handleLocationUpdate = throttle((e) => {
const { lat, lng } = e.detail;
map.setView([lat, lng], 14);
}, 1000);
window.addEventListener('location:update', handleLocationUpdate);
注意:此处节流的是 handler 执行,不是事件监听本身,因此不会丢失事件,只是合并处理时机。
避免误用:不要节流生命周期类事件
像 'app:mount'、'user:login'、'route:change' 这类语义明确、不可合并的关键事件,绝对不能节流。它们代表离散状态跃迁,延迟或丢弃会直接导致功能异常:
- 节流 'user:login' → 登录态同步延迟,子应用可能因未收到而反复请求 token
- 节流 'app:unmount' → 主应用无法及时清理监听器,引发内存泄漏
这类事件应走直通路径,零延迟分发。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











