Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现发布订阅者模式 #10

Open
Ray1993 opened this issue Jan 15, 2018 · 0 comments
Open

实现发布订阅者模式 #10

Ray1993 opened this issue Jan 15, 2018 · 0 comments

Comments

@Ray1993
Copy link
Owner

Ray1993 commented Jan 15, 2018

发布订阅者模式:

常被称作观察者模式,或者消息机制,定义了一种依赖关系,主要是用来解决对象之间的耦合;

使用的案例:

  1. Vue实现数据的深度响应,就用到了发布订阅模式的原理,视图订阅了其依赖的数据,数据改变则会通过notify,通知视图去刷新;
  2. D3.js的事件机制dispatch,也是通过利用了发布订阅模式;

特点:一般在全局中定义,保证在任何地方都可以发布和订阅;

代码:

class Observer{
   constructor(){
     this.evenlist = []
   }
   on(even,fun){                                                  //注册
      if(typeof this.evenlist[even]==='undefined'){
          this.evenlist[even] = [fun];
          return;
      }
      for(let i =0 ;i< this.evenlist[even].length ;i++){
        if(this.evenlist[even][i] === fun) return;
      }
      this.evenlist[even].push(fun);
   }
   fire(even,args){                                               //触发
      if(typeof this.evenlist[even]==='undefined'){
         throw 'even is undefined';
         return;
      }
      this.evenlist[even].forEach(sub => {
          sub.call(this,args)
      })
   }
   remove(even,fun){                                            //移除
      if(typeof this.evenlist[even]==='undefined'){
         throw 'even is undefined';
         return;
      }
      this.evenlist[even] = this.evenlist[even].filter(sub => sub !== fun)
   }
}

let ob = new Observer();
function fn1(agrs) {
  console.log("注册成功第1次");
  console.log(agrs)
}
function fn2(agrs) {
  console.log("注册成功第2次");
  console.log(agrs)
}
function fn3(agrs) {
  console.log("注册成功第3次");
  console.log(agrs)
}
ob.on("click", fn1);
ob.on("click", fn2);
ob.on("click", fn3);
ob.remove("click", fn2);
ob.fire("click", "传参成功");

控制台输出结果:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant