手写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有用'