手写EventHub--TDD

453 阅读1分钟

手写EventHub

EventHub 类

class EventHub {
  private cache: {[key: string]: Array<(data: unknown) => void>} = {} // 存储事件名(eventName)和事件回调(fn)
  
  // 订阅 存储事件回调fn
  on(eventName: string, fn: (data; unknown) => void) {
    this.cache[eventName] = this.cache[eventName] || [] // 初始化
    this.cache[eventName].push(fn)
  }
  
  // 发布 调用eventName对应的所有的fn
  emit(eventName: string, data?: unknown) {
    if(this.cache[eventName] === undefined) return
    this.cache[eventName].forEach((fn) => fn(data))
  }
  
  // 取消订阅 将fn从this.cache[eventName] 数组中删除
  off(eventName: string, fn: (data:unknown) => void) {
    let index = indexOf(this.cache[eventName], fn)
    if (index === -1) return
    this.cache[eventName].splice(index, 1)
  } 
}
export default EventHub

/**
 *
 * @param array 帮组函数 helper indexOf
 * @param item
 */
function indexOf(array, item) {
    if (array === undefined) return -1 // off就不需要初始化了 this.cache[eventName] = this.cache[eventName] || []
    let index = -1
    for (let i = 0; i < array.length; i++) {
        if (array[i] === item) {
            index = i
            break
        }
    }
    return index
}

测试驱动开发(TDD)

import EventHub from '../eventHub.ts';
type TestCase = (message: string) => void
  • 测试一

Assert eventHub可以创建对象

const test1: TestCase = message => {
  const eventHub = new EventHub()
  console.assert(eventHub instanceof Object === true, 'eventHub 是个对象')
  console.log(message)
}
test1('eventHub 可以创建对象') // 执行
// 执行结果
// 无报错
// 输出 'eventHub 可以创建对象'
  • 测试二

订阅了(.on)之后, 发布(.emit)会触发订阅(.on)的函数

const test2: TestCase = message => {
  const eventHub = new EventHub()
  let called = false
  // 订阅 事件名xxx fn=> assert
  eventHub.on('xxx', (data) => {
    called = true
    console.assert(data === 'Hello EventHub')
  })
  // 发布
  eventHub.emit('xxx', 'Hello EventHub')
  
  // 确保函数执行
  console.assert(called === true)
  console.log(message)
}

test2('.on 了之后 .emit 会触发 .on 的函数') // 执行
// 执行结果
// 无报错
// 输出 '.on 了之后 .emit 会触发 .on 的函数'
  • 测试三

assert 取消订阅(.off)有用

const test3: TestCase = message => {
  const eventHub = new EventHub()
  let called = false
  const fn1 = () => {
    called = true
  }
  
 	// 订阅
  eventHub.on('yyy', fn1)
  // 订阅之后立即取消订阅
  eventHub.off('yyy', fn1)
  // 取消之后在发布
  eventHub.emit('yyy')
  
  // assert
  console.assert(called === false)
  console.log(meessage)
}

test3('.off有用') // 执行
// 执行结果
// 无报错 fn1已被删除
// 输出 '.off有用'