面试题 : 手写发布订阅

55 阅读1分钟

常规写法

const eventHub = { 
map: { 
// click: [f1 , f2] 
},

on: (name, fn)=>{ 
  eventHub.map[name] = eventHub.map[name] || [] 
  eventHub.map[name].push(fn) 
}, 
  
emit: (name, data)=>{ 
  const q = eventHub.map[name] 
  if(!q) return 
  q.map(f => f.call(null, data)) 
  return undefined 
}, 
 
 off: (name, fn)=>{ 
   const q = eventHub.map[name] 
   if(!q){ return } 
   const index = q.indexOf(fn) 
   if(index < 0) { return } 
   q.splice(index, 1) } 
 } 
   
 // 使用 
  const msg = (e)=>{
      console.log(e,'订阅了事件')
    }
    eventHub.on('click', msg)
    eventHub.emit('click', 'tang')  // tang,订阅了事件
    eventHub.off('click',msg)

class写法

class EventHub {
  map = {} 
  on(name, fn) { 
    this.map[name] = this.map[name] || [] 
    this.map[name].push(fn) } 
  emit(name, data) { 
    const fnList = this.map[name] || [] 
    fnList.forEach(fn => fn.call(undefined, data)) } 
  off(name, fn) { 
    const fnList = this.map[name] || [] 
    const index = fnList.indexOf(fn) 
    if(index < 0) return fnList.splice(index, 1) } } 
    
    // 使用 
    const msg = (e)=>{
      console.log(e,'订阅了事件')
    }
    const E = new EventHub() 
    E.on('click', msg)
    E.emit('click', 'tang')  // tang,订阅了事件
    E.off('click',msg)