发布订阅模式在很多地方都用到了,但是我自己经常忘记这块咋写,今天正好自己梳理一遍这块的逻辑
简介
发布订阅模式有两个角色
发布者:发布事件或者消息
订阅者:订阅了发布者的事件或消息,并在事件发生时做出响应
图解:
在订阅发布模式中,发布者将事件发送到事件总线或事件管理器中,然后订阅者订阅感兴趣的事件。当事件发生时,事件总线或事件管理器会通知所有订阅了该事件的订阅者,并调用它们预先注册的回调函数,从而实现了一种松耦合的通信方式。
自定义实现
发布、订阅功能
class EventEmitter {
constructor() {
this.list = {}
}
// 订阅事件
on(event, callback) {
if (!this.list[event]) {
this.list[event] = []
}
this.list[event].push(callback)
}
// 触发事件
emit(event, ...args) {
if (this.list[event]) {
this.list[event].forEach(fn => {
fn.apply(this, args)
});
}
}
}
function hello(...data) {
console.log('hello' + data);
}
function world(...data) {
console.log('world' + data);
}
const emitter = new EventEmitter()
// 订阅事件
emitter.on('onSell', hello)
emitter.on('onSell', world)
// 触发指定事件,执行对应的回调函数
emitter.emit('onSell', '1', '2', '3')
详细说明:
- EventEmitter 类用于管理事件的订阅和触发。
- on(event, callback) 方法用于订阅事件。当事件被触发时,对应的回调函数会被调用。
- emit(event) 方法用于触发事件。当事件被触发时,所有订阅该事件的回调函数都会被依次调用。
输出:
hello1,2,3
world1,2,3
取消功能
class EventEmitter {
constructor() {
this.list = {}
}
// 订阅事件
on(event, callback) {
if (!this.list[event]) {
this.list[event] = []
}
this.list[event].push(callback)
}
// 触发事件
emit(event, ...args) {
if (this.list[event]) {
this.list[event].forEach(fn => {
fn.apply(this, args)
});
}
}
// 取消订阅指定事件的指定回调函数
off(event, callback) {
if (this.list[event]) {
this.list[event] = this.list[event].filter(fn => fn !== callback)
}
}
}
function hello(...data) {
console.log('hello' + data);
}
function world(...data) {
console.log('world' + data);
}
const emitter = new EventEmitter()
// 订阅事件
emitter.on('onSell', hello)
emitter.on('onSell', world)
emitter.off('onSell', hello)
// 触发指定事件,执行对应的回调函数
emitter.emit('onSell', '1', '2', '3')
详细说明:
- off(event, callback) 方法用于取消订阅指定事件的指定回调函数。
输出:
world1,2,3
仅订阅一次事件功能
class EventEmitter {
constructor() {
this.list = {}
}
// 订阅事件
on(event, callback) {
if (!this.list[event]) {
this.list[event] = []
}
this.list[event].push(callback)
}
// 触发事件
emit(event, ...args) {
if (this.list[event]) {
this.list[event].forEach(fn => {
fn.apply(this, args)
});
}
}
// 取消订阅指定事件的指定回调函数
off(event, callback) {
if (this.list[event] && callback) {
this.list[event] = this.list[event].filter(fn => fn !== callback)
}
}
// once方法用于仅订阅一次事件,即回调函数只会被执行一次
once(event, callback) {
const onceCallback = (...args) => {
callback.apply(this, args)
this.off(event, onceCallback)
}
this.on(event, onceCallback)
}
}
function hello(...data) {
console.log('hello' + data);
}
const emitter = new EventEmitter()
// 使用 once 方法订阅事件,回调函数只会被执行一次
emitter.once('onSell', hello)
// 触发事件,只会执行一次回调函数
emitter.emit('onSell', '1', '2', '3')
emitter.emit('onSell', '1', '2', '3')
详细说明:
- once(event, callback)方法用于订阅事件,但是事件在第一次被调用以后就被移除,相当于取消订阅,之后再次触发事件,订阅者也不会收到此事件的回调函数所发送的消息。
输出:
hello1,2,3