js实现简单的【发布者-订阅者模式】
发布订阅模式是什么
发布订阅模式是一种代码的设计模式,它允许对象间进行松散耦合的通信。
发布者(Publishers)不会直接调用订阅者(Subscribers),相反,它们通过事件通道发布消息;订阅者通过注册监听事件通道上的消息来做出响应。
这种模式在事件驱动编程和异步编程中非常有用。
发布订阅模式怎么实现
发布订阅模式在前端开发中有广泛的应用。例如,事件处理、状态管理库(如 Redux)、消息中间件、数据流控制等
1)一个用于存储事件及其对应回调的事件中心。
2)一个 on 方法,用于订阅某个事件,并将回调函数注册到事件中心中。
3)一个 emit 方法,用于发布某个事件,并调用所有订阅该事件的回调函数。
4)一个 off 方法,用于解除订阅。
使用场景:
发布-订阅模式可用于解耦复杂的代码逻辑,例如:
浏览器中的事件处理(如点击,输入等);
背景任务和前台任务之间的通信;
多模块或组件之间的通信。
高级实现:
在实际开发中,我们可能会用到一些更复杂的发布-订阅库比如 EventEmitter (Node.js 内置)、PubSubJS 等,这些库提供了更具备鲁棒性的实现和更多特性。
代码
let eventEmitter ={
//事件中心
events:{},
//订阅事件
on: function (eventName,callback)
{
//如果事件不存在
if(!this.events[eventName])
{
this.events[eventName] = [];
}
this.events[eventName].push(callback);
},
//发布事件 事件触发
emit:function (eventName,...args)
{
// 事件不存在
if(!this.events[eventName])
{
return ;
}
this.events[eventName].forEach(callback =>{
callback(...args)
})
},
//取消事件
off:function (eventName,callback)
{
if(this.events[eventName])
{
this.events[eventName] = this.events[eventName].filter(e=>e!==callback)
}
},
/**
* 这里的 args 并没有在 once 函数的参数列表中明确声明,
* 而是作为 onceWrapper 函数的一个内部变量(通过剩余参数语法捕获)。
* 这是因为 onceWrapper 函数不知道它会接收多少个参数,
* 所以它使用 ...args 来捕获所有参数,并将它们作为一个数组处理
* 。然后,它可以通过 callback(...args) 将这些参数传递给 callback 函数
*/
//一次性订阅
once:function (eventName,callback)
{
const onceWrapper = (...args)=>{
callback(...args)
//执行一次后取消订阅
this.off(eventName,onceWrapper)
}
this.on(eventName,onceWrapper)
}
}
//示例
//用户定义的回调函数
function user1(msg){
console.log("user1 ",msg);
}
function user2(msg){
console.log("user2 ",msg);
}
function user3(msg){
console.log("user3 ",msg);
}
//注册事件
eventEmitter.on("test",user1)
eventEmitter.on("test",user2)
//事件触发
eventEmitter.emit("test","这是一个测试")
//取消订阅
eventEmitter.off('test', user1);
// 发布
eventEmitter.emit('test', '这次只有 User2 收到消息');
//一次性订阅注册
eventEmitter.once("once",user3)
//事件触发两次
eventEmitter.emit("once","test by user3")
eventEmitter.emit("once","test by user3")//没有输出