ts手写EventHub+测试用例

120 阅读1分钟

EventHub(发布订阅模式)

// index.ts
class EventHub {
  cache: { [key: string]: Array<(data: unknown) => void> } = {} // xxx: [fn1,fn2],
  //unknown 用过一次类型后不能修改 any 可以
  on(eventName: string, fn: (data: unknown) => void) {
    this.cache[eventName] = this.cache[eventName] || []
    this.cache[eventName].push(fn)
  }
  emit(eventName: string, data?: unknown) {
    ;(this.cache[eventName] || []).forEach((fn) => fn(data))
  }
  off(eventName: string, fn: (data: unknown) => void) {
    this.cache[eventName] = this.cache[eventName] || []
    const index = this.cache[eventName].indexOf(fn)
    if (index !== -1) {
      this.cache[eventName].splice(index, 1)
    }
  }
}

export default EventHub

测试用例(console.assert)

// test.ts
import EventHub from './index.ts'

type TestCase = (message: string) => void

const test1: TestCase = (message) => {
  const eventHub = new EventHub()
  console.assert(eventHub instanceof Object === true, 'eventHub是个对象')
  console.log(message)
}

const test2: TestCase = (message) => {
  let called = false
  const eventHub = new EventHub()
  eventHub.on('xxx', (data) => {
    called = true
    console.assert(data === '这是一个数据')
  })
  eventHub.emit('xxx', '这是一个数据')
  setTimeout(() => {
    console.assert(called === true)
    console.log(message)
  }, 1000)
}

const test3: TestCase = (message) => {
  const eventHub = new EventHub()
  let called = false
  const fn = () => {
    called = true
  }
  eventHub.on('yyy', fn)
  eventHub.off('yyy', fn)
  eventHub.emit('yyy')
  setTimeout(() => {
    console.assert(called === false)
    console.log(message)
  }, 1000)
}

test1('EventHub 创建对象')
test2('.on之后.emit 会触发.on函数')
test3('.off 取消了订阅')

如何运行测试用例

yarn global add ts-node

ts-node test.ts