JS中的发布-订阅者模式
一、前言
学习vue的时候,对深入响应式原理模模糊糊的,现在简单一下理解。
二、简述VUE响应原理。
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应的监听回调。
三、什么是发布-订阅者模式
简单理解:比如一个商店,会员粉丝经常要询问有什么活动,员工每次都要做一遍解答,工作重复又麻烦,但是把所有会员的邮箱收集成名单,有活动时统一发送邮件。会员就是订阅者,商店就是发布者会在合适的时候遍历名单,依次给会员发布消息。发送邮件通知就是一个的发布—订阅模式
多个订阅者(一般是注册的函数)同时监听同一个数据对象,当这个数据对象发生变化的时候会执行一个发布事件,通过这个发布事件会通知到所有的订阅者,使它们能够自己改变对数据对象依赖的部分状态。
四、发布订阅者模式的作用
主要为了处理一对多的场景,应用于不同情况下的不同函数的调用
优点:耦合性低,便于代码的维护
缺点:创建订阅者本身要消耗一定的时间和内存,可能订阅的消息未发生,但这个订阅者会始终存在于内存中
五、代码示例
- 创建发布-订阅者模式的对象
function Event () {
this.handlers = {};
}
Event .prototype = {
// 订阅事件
on: function(eventType, handler){
var self = this;
if(!(eventType in self.handlers)) {
self.handlers[eventType] = [];
}
self.handlers[eventType].push(handler);
return this;
},
// 触发事件(发布事件)
emit: function(eventType){
var self = this;
var handlerArgs = Array.prototype.slice.call(arguments,1);
for(var i = 0; i < self.handlers[eventType].length; i++) {
self.handlers[eventType][i].apply(self,handlerArgs);
}
return self;
},
// 删除订阅事件
off: function(eventType, handler){
var currentEvent = this.handlers[eventType];
var len = 0;
if (currentEvent) {
len = currentEvent.length;
for (var i = len - 1; i >= 0; i--){
if (currentEvent[i] === handler){
currentEvent.splice(i, 1);
}
}
}
return this;
}
};
- 使用发布-订阅者模式
let Publisher = new Event ();
//订阅事件a
Publisher.on('a', function(e){
console.log(1 + e);
});
Publisher.on('a', function(e){
console.log(2 + e);
});
//触发事件a
Publisher.emit('a', '我是第1次调用');
Publisher.emit('a', '我是第2次调用');