用闭包实现事件总线的核心是封装 handlers 对象与 on/off/emit 方法,确保事件监听器隔离、支持多回调、精确移除、参数透传且不污染全局。

在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
<p>用闭包实现事件总线的核心,是把事件监听器列表和触发逻辑封装在私有作用域里,避免全局污染,同时提供干净的 <code>on</code>、<code>off</code>、<code>emit</code> 接口。</p>
<H3>封装事件映射表与操作方法</H3>
<p>闭包内部维护一个对象 <code>handlers</code>,键为事件名,值为监听函数数组。所有增删查都只通过返回的公共方法进行,外部无法直接访问或修改内部状态。</p>
<p>关键点:每个事件名对应独立的监听器数组,支持同一事件绑定多个回调;取消订阅时精确匹配函数引用(不能靠名字或字符串),所以必须保留原始函数引用。</p>
<H3>提供 on(订阅)与 off(取消)方法</H3>
<p><code>on(eventName, callback)</code> 将回调推入对应事件的数组;<code>off(eventName, callback)</code> 遍历并用 <code>===</code> 移除指定函数(注意不是 <code>splice(0,1)</code> 这种盲目删除)。</p>
<ul>
<li>如果没传 <code>callback</code>,可支持清空该事件所有监听器</li>
<li>确保重复 <code>on</code> 同一函数不会重复添加(可选增强)</li>
<li><code>off</code> 时若函数不存在,静默忽略,不报错</li>
</ul>
<H3>实现 emit(触发)并支持参数透传</H3>
<p><code>emit(eventName, ...args)</code> 查找该事件的所有监听器,按注册顺序依次调用,并把参数原样传入。若事件无监听器,不报错也不做任何事。</p>
<p>可选增强:支持异步触发(用 <code>Promise.all</code> 并行执行)或顺序等待(<code>reduce + async/await</code>),但基础版本保持同步即可。</p>
<H3>完整可运行示例</H3>
<p>下面是一个轻量、无依赖的实现:</p>
<font color="#888">
<pre>
function createEventBus() {
const handlers = {};
return {
on(eventName, callback) {
if (!handlers[eventName]) {
handlers[eventName] = [];
}
handlers[eventName].push(callback);
},
off(eventName, callback) {
if (!handlers[eventName]) return;
if (!callback) {
handlers[eventName] = [];
return;
}
const index = handlers[eventName].indexOf(callback);
if (index > -1) {
handlers[eventName].splice(index, 1);
}
},
emit(eventName, ...args) {
const callbacks = handlers[eventName];
if (callbacks && callbacks.length) {
callbacks.forEach(cb => cb(...args));
}
}
};
}
// 使用示例:
const bus = createEventBus();
const handler1 = () => console.log('收到消息');
const handler2 = (msg) => console.log('带参:', msg);
bus.on('login', handler1);
bus.on('login', handler2);
bus.emit('login', 'success'); // 输出两行
bus.off('login', handler1);
bus.emit('login', 'again'); // 只输出第二行
</pre>
</font>

















