摘要:发布订阅者模式,一种对象间一对多的依赖关系,但一个对象的状态发生改变时,所依赖的它的对象都将得到状态改变的通知
主要的作用
1、广泛应用于异步编程中(替代了传递回调函数)
2、对象之间松散耦合的编写代码
缺点
1、创建订阅者本身要消耗一定的时间和内存
2、多个发布者和订阅者嵌套在一起是时候,程序难以跟踪维护
实现的思路
1、创建一个事件中心(缓存列表)
2、on方法用来把回调函数fn都加到事件中心中
3、emit方法取到arguments里第一个当做event,根据event值去执行对应事件中心中的函数
5、 once实现事件的单次订阅
4、off方法可以根据event值取消订阅
class Event {
//事件中心,存放事件和回调函数
constructor() {
this._events = {}
}
on(eventName, callback) {
// 由于一个事件可能注册多个回调函数,所以使用数组来存储事件队列
const callbacks = this._events[eventName] || [];
callbacks.push(callback);
this._events[eventName] = callbacks
}
emit(eventName, ...args) {
//由于一个事件可能注册多个回调函数,所以使用数组来存储事件队列
const callbacks = this._events[eventName] || [];
callbacks.forEach(cb => cb(...args))
}
once(eventName, callback) {
const one = (...args) => {
callback(...args)
this.off(eventName, one)
}
// 由于:我们订阅事件的时候,修改了原回调函数的引用,所以,用户触发 off 的时候不能找到对应的回调函数
// 所以,我们需要在当前函数与用户传入的回调函数做一个绑定,我们通过自定义属性来实现
one.initialCallback = callback;
this.on(eventName, one)
}
off(eventName, callback) {//取消订阅,如callback不传,直接取消该事件所有订阅信息
const callbacks = this._events[eventName] || []
const newCallBacks = callback ? callbacks.filter(fn => fn != callback && fn.initialCallback != callback /* 用于once的取消订阅 */) : []
this._events[eventName] = newCallBacks
}
}
const events = new Event()
events.on("hello", function () {
console.log("hello");
})
let cb = function () {
console.log('cb');
}
events.once("hello", cb)
events.emit("hello")
//hello
//cb
events.emit("hello")
//hello