js发布订-阅模式之实现 js 自定义事件(面试题 )

一、前言
写这篇文章还要从一个面试题开始,前几天投了猫眼的暑期实习,在二面中就遇到这样一个题,当时绞尽脑袋都没有想出来(当然也顺利的挂在二面上了),虽然楼主之前的有学过发布-订阅模式,但是自定义事件的从来没写过,当时就想,‘我还是个学生啊,丧心病狂的面试官怎么能给我出这种题’。
好在后来学习了一下,其实也不是那么难
二 ,发布-订阅模式
  发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知。
  就和用户订阅微信公众号道理一样,一个公众号可以被多个用户同时订阅,当公众号有新增内容时候,只要发布就好了,用户就能接收到最新的内容。
  js中的事件监听机制就是一种观察者模式。

三 ,面试原题

事件监听和触发.jpg

首先分析有三个测试用例
1,第一个测试用例监听foo事件并打印字符串
2,第二个测试用例监听foo事件并打印传过来的参数
3,第三个测试用例监听bar事件并打印传过的的二个参数

思路:定义一个myEvent对象,里面有oberverEvent属性,订阅事件的on 方法,触发事件的trigger方法

function myEvent(){
 this.observerEvent={}
 this.on=function(eventType,handler){    //eventType为事件名,handler为调用on时传过来的函数名
 }
 this.trigger=function(eventType)   //eventType为触发的事件名
}

以下为完整代码

  function myEvent(){
      this.observerEvent={}
      this.on=function(eventType,handler){
        if(! (eventType in this.observerEvent)){   //如果没有订阅该事件,则该事件为空数组
          this.observerEvent[eventType]=[]    
        }
        this.observerEvent[eventType].push(handler) //同一个订阅事件的回调会放在一个数组里
        return this
      }
      this.trigger=function(eventType){
        let ev=Array.prototype.slice.call(arguments,0,1)  //获取t触发trigger()时的 第一个参数,为触发时的事件名
        let args=Array.prototype.slice.call(arguments,1) //获取触发trigger()传过来的全部参数
        for(let event in this.observerEvent){  //遍历observerEvent
          if(ev==eventType){                         //判断ev事件是否已经在(订阅)observerEvent里
            for(let i=0;this.observerEvent[ev].length >i ;i++){ //遍历ev里所有的函数,并执行
            this.observerEvent[ev][i](...args)
          }
          }
         }
       }
       return this
    }
    let event=new myEvent()
        event.on('foo',function(){
           console.log('foo fire')
        })
        event.on('foo',function(a){
          console.log(a)
        })
        event.on('bar',function(a,b){
          console.log(a + ' ' + b)
        })
        event.trigger('foo')
        event.trigger('foo',1)
        event.trigger('bar',2,3)

你可能感兴趣的:(js发布订-阅模式之实现 js 自定义事件(面试题 ))