这是我参与更文挑战的第9天,活动详情查看: 更文挑战
定义
发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。在javascript开发中,一般用事件模型来替代传统的发布—订阅模式。将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相应对象间的一致性,这样会给维护、扩展和重用都带来不便。当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象需要改变时,就可以使用订阅发布模式了。 一个抽象模型有两个方面,其中一方面依赖于另一方面,这时订阅发布模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。订阅发布模式所做的工作其实就是在解耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。
我们可以实现简单的on与emit方法。代码如下:
class Event {
constructor(){
this.obj = {}
}
//函数接收两个参数,事件名,事件触发后的函数。subscribe函数负责将提供的函数存放到对应的事件数组中。
this.on = (name,fn)=>{
if(!this.obj[name]){
this.obj[name] = [];
}
this.obj[name].push(fn);
}
//考虑到某个模块可能会触发多个事件
this.emit = (name,val)=>{
if(this.obj[name]){
this.obj[name].map((fn)=>{
fn(val);
});
}
}
//模块还可以取消订阅。函数接收两个参数,取消订阅的事件名、对应的函数。若不传入函数,则默认清除事件对应的所有函数。
this.off = (name,fn)=>{
if(this.obj[name]){
if(fn){
let index = this.obj[name].indexOf(fn);
if(index > -1){
this.obj[name].splice(index,1);
}
}else{
this.obj[name].length = 0;
//设长度为0比obj[name] = []更优,因为如果是空数组则又开辟了一个新空间,设长度为0则不必开辟新空间
}
}
}
}