javascript可通过闭包实现轻量pub/sub消息总线,核心是用闭包封装私有handlers映射表,暴露on/emit/off方法;支持返回解绑函数、通配符匹配(可选)及内存安全清理机制。

JavaScript 中可以通过闭包封装事件监听器和触发逻辑,实现轻量、隔离、无依赖的发布订阅模式(Pub/Sub)消息总线。核心是利用闭包保存内部的事件映射表(如 handlers),对外只暴露 on、emit、off 等方法,避免全局污染和外部误操作。
用闭包封装事件注册与分发逻辑
闭包让事件处理器列表私有化,不被外部直接访问或修改,确保数据安全性和行为一致性。
基本结构如下:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 外层函数返回一个对象,包含
on(订阅)、emit(发布)、off(取消订阅)方法 - 内层变量
handlers是一个 Map 或普通对象,以事件名(字符串)为键,存储回调函数数组 - 每次
on调用只往对应事件的数组里推入新回调;emit则遍历并执行该数组所有回调
支持通配符与事件解耦(可选增强)
基础版只支持精确匹配事件名,但通过简单扩展可支持类似 "user.*" 的通配订阅:
- 在
on时判断是否含"*",将通配规则单独存入wildcards数组 -
emit("user.login")时,除匹配"user.login"外,也遍历wildcards,用event.startsWith(pattern.replace(/\*/g, ""))匹配 - 注意:通配逻辑会轻微影响性能,高频场景建议慎用或改用更成熟的库(如 mitt)
自动清理与内存安全(防泄漏)
闭包本身不解决内存泄漏,需主动设计清理机制:
-
off方法应支持移除指定回调,或清空某事件所有监听器 - 推荐给每个
on返回一个off函数(即“订阅句柄”),方便使用者按需解绑 - 示例:
const unsubscribe = bus.on("data", handler); unsubscribe(); - 避免长期持有对大对象或 DOM 元素的引用,尤其在回调中 —— 闭包会延长其生命周期
一个简洁可用的实现示例
以下是一个生产可用、带解绑句柄的闭包式消息总线:
function createEventBus() {
const handlers = new Map();
function on(event, callback) {
if (!handlers.has(event)) {
handlers.set(event, []);
}
const list = handlers.get(event);
list.push(callback);
return () => {
const index = list.indexOf(callback);
if (index > -1) list.splice(index, 1);
};
}
function emit(event, ...args) {
const list = handlers.get(event);
if (list) list.forEach(cb => cb(...args));
}
function off(event, callback) {
if (!callback) {
handlers.delete(event);
} else {
const list = handlers.get(event);
if (list) {
const index = list.indexOf(callback);
if (index > -1) list.splice(index, 1);
}
}
}
return { on, emit, off };
}
// 使用
const bus = createEventBus();
const un = bus.on("login", (user) => console.log("Welcome", user));
bus.emit("login", { name: "Alice" });
un(); // 取消订阅
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










