第33题 实现一个发布订阅者模式
简介:
发布订阅者模式,一种对象间一对多的依赖关系,但一个对象的状态发生改变时,所依赖它的对象都将得到状态改变的通知。
主要的作用(优点):
- 广泛应用于异步编程中(替代了传递回调函数)
- 对象之间松散耦合的编写代码
缺点:
- 创建订阅者本身要消耗一定的时间和内存
- 多个发布者和订阅者嵌套一起的时候,程序难以跟踪维护
实现的思路:
- 创建一个对象(缓存列表)
- on方法用来把回调函数fn都加到缓存列表中
- emit方法取到arguments里第一个当做key,根据key值去执行对应缓存列表中的函数
- remove方法可以根据key值取消订阅
coding:
let event = {
list: {},
on (key, fn) {
if (!this.list[key]) {
this.list[key] = [];
}
this.list[key].push(fn);
},
emit () {
let key = [].shift.call(arguments),
fns = this.list[key];
if (!fns || fns.length <= 0) {
return false;
}
fns.forEach(fn => {
fn.apply(this, arguments);
})
},
remove (key, fn) {
let fns = this.list[key];
if (!fns || fns.length <= 0) {
return false;
}
if (!fn) {
fns && (fns.length = 0);
} else {
fns.forEach((cb, i) => {
if (cb === fn) {
fns.splice(i, 1);
}
})
}
}
}
function cat () {
console.log('喵喵喵~');
}
function dog () {
console.log('汪汪汪~');
}
function hasArgs (args) {
console.log(args);
}
event.on('pet', hasArgs);
event.on('pet', cat);
event.on('pet', dog);
event.remove('pet', dog)
event.emit('pet', '我是传递的参数');
// 结果:
// '我是传递的参数'
// '喵喵喵~'
工作中的应用:
- 插广告
- 打点
发布订阅者模式和观察者模式的区别?
- 发布/订阅模式是观察者模式的一种变形,两者区别在于,发布/订阅模式在观察者模式的基础上,在目标和观察者之间增加一个调度中心。
- 观察者模式 是由具体目标调度,比如当事件触发,Subject 就会去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的。
- 发布/订阅模式 由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。
