闭包能实现观察者模式是因为它提供了私有且持久的变量存储,使得订阅者列表\_subscribers被安全封装在函数作用域内,外部无法直接访问;2. subscribe、unsubscribe和notify方法通过闭包共享\_subscribers数组,实现对观察者的增删查和通知;3. 每次调用createeventbus都会创建独立的闭包环境,保证多个实例间互不干扰;4. 实际使用中需注意内存泄漏问题,即组件销毁时应主动取消订阅以避免残留回调引用导致无法回收;5. 通知顺序依赖订阅顺序,若需优先级控制则需扩展逻辑;6. 单个观察者报错可能中断通知流程,因此需用try...catch包裹回调执行以确保其他观察者仍能收到消息;7. 在复杂场景下,手动管理大量事件和订阅者会变得困难,建议引入eventemitter或rxjs等专业库进行更高效的事件流管理。

说实话,用JavaScript闭包来实现观察者模式,这事儿真挺巧妙的。它核心的思路就是,让一个函数(或者说,它返回的对象)能记住并管理它自己的一堆“听众”——那些对它的状态变化感兴趣的部分。这样,当它内部发生点什么事儿的时候,就能悄咪咪地通知到所有这些听众,而且这个听众列表还是它自己的私有财产,外面轻易动不了。

要实现这套机制,我们通常会创建一个函数,这个函数内部维护一个数组来存放所有的观察者(也就是那些回调函数)。然后,它会暴露出几个方法:一个用来添加观察者(
subscribe
unsubscribe
notify
我个人觉得,闭包和观察者模式简直是天作之合。你想啊,观察者模式的核心不就是“一个主体(发布者)要管理一堆订阅者,并在特定事件发生时通知它们”吗?这里面最关键的一点,就是那个订阅者列表,它必须是主体的“私有财产”,不能随便被外部篡改,同时还得是持久化的,不能每次调用都重新初始化。闭包天然就提供了这种私有性和持久性。它把
observers
subscribe
unsubscribe
立即学习“Java免费学习笔记(深入)”;

来,我们直接看段代码,这样更直观。假设我们要创建一个简单的事件发布器:
function createEventBus() {
let _subscribers = []; // 这是一个私有变量,通过闭包保持持久性
return {
/**
* 订阅事件
* @param {Function} callback - 观察者回调函数
* @returns {Function} - 返回一个取消订阅的函数,方便链式调用或直接取消
*/
subscribe: function(callback) {
if (typeof callback !== 'function') {
console.warn('订阅者必须是一个函数!');
return;
}
_subscribers.push(callback);
console.log('有新的订阅者加入!当前订阅数:', _subscribers.length);
// 返回一个取消订阅的函数,这是个很实用的模式
// 注意:这里的 `this` 指向返回的对象,确保 unsubscribe 正确调用
return () => {
this.unsubscribe(callback);
};
},
/**
* 取消订阅
* @param {Function} callback - 要移除的观察者回调函数
*/
unsubscribe: function(callback) {
_subscribers = _subscribers.filter(sub => sub !== callback);
console.log('有订阅者离开了。当前订阅数:', _subscribers.length);
},
/**
* 通知所有订阅者
* @param {*} data - 要传递给观察者的数据
*/
notify: function(data) {
console.log('开始通知所有订阅者...');
_subscribers.forEach(callback => {
try {
callback(data);
} catch (error) {
// 实际项目中这里可能需要更复杂的错误处理,比如记录日志
console.error('通知某个订阅者时出错:', error);
}
});
console.log('通知完成。');
}
};
}
// 使用示例:
const myEventBus = createEventBus();
// 观察者1
const observer1 = (message) => {
console.log('观察者1 收到消息:', message);
};
// 观察者2
const observer2 = (message) => {
console.log('观察者2 收到消息:', message.toUpperCase());
};
// 订阅
const unsubscribe1 = myEventBus.subscribe(observer1);
myEventBus.subscribe(observer2);
myEventBus.subscribe((data) => { // 匿名函数也可以
console.log('匿名观察者收到:', data.length, '个字符');
});
console.log('\n--- 第一次通知 ---');
myEventBus.notify('Hello World');
// 取消订阅一个观察者
unsubscribe1(); // 或者 myEventBus.unsubscribe(observer1);
console.log('\n--- 第二次通知 ---');
myEventBus.notify('Goodbye');
// 尝试订阅一个非函数
myEventBus.subscribe('not a function');这段代码里,
_subscribers
createEventBus
createEventBus()
_subscribers
myEventBus
subscribe
unsubscribe
notify
_subscribers
createEventBus

虽然闭包实现观察者模式很优雅,但实际使用中还是有些坑或者说需要注意的地方:
_subscribers
useEffect
beforeDestroy
forEach
notify
try...catch
subscribe
unsubscribe
以上就是javascript闭包怎样实现观察者模式的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号