简单实现on与emit方法

1,354 阅读2分钟

这是我参与更文挑战的第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则不必开辟新空间
            }  
        }
    }

}