$ yarn add global ts-node

确定API 以及 测试用例

  • EventHub#on
  • EventHub#off
  • EventHub#emit

/src/index.ts

  1. class EventHub {
  2. cache = {}
  3. on(eventName, fn) {
  4. this.cache[eventName] = this.cache[eventName] || []
  5. this.cache[eventName].push(fn)
  6. }
  7. emit(eventName, data?) {
  8. (this.cache[eventName] || []).forEach(fn => fn(data))
  9. }
  10. off(eventName, fn) {
  11. this.cache[eventName] = this.cache[eventName] || []
  12. let index = indexOf(this.cache[eventName], fn)
  13. if (index === -1) return
  14. this.cache[eventName].splice(index, 1)
  15. }
  16. }
  17. export default EventHub
  18. /* 帮助函数indexOf */
  19. function indexOf(array, item) {
  20. if (array === undefined) return -1
  21. let index = -1
  22. for (let i = 0; i < array.length; i++) {
  23. if (array[i] === item) {
  24. index = i
  25. break
  26. }
  27. }
  28. return index
  29. }

/test/index.ts

  1. import EventHub from '../src/index';
  2. const test1 = (message) => {
  3. const eventHub = new EventHub()
  4. console.assert(eventHub instanceof Object === true, "eventHub 是个对象")
  5. console.log(message)
  6. }
  7. const test2 = (message) => {
  8. const eventHub = new EventHub()
  9. let called = false
  10. eventHub.on("xxx", (data) => {
  11. called = true
  12. console.log("男篮", data)
  13. })
  14. eventHub.emit("xxx", "迈特凯")
  15. setTimeout(() => {
  16. console.assert(called)
  17. console.log(message)
  18. }, 1000)
  19. }
  20. const test3 = (message) => {
  21. const eventHub = new EventHub()
  22. let called = false
  23. const fn = () => {
  24. called = true
  25. console.log("yyy")
  26. }
  27. eventHub.on("yyy", fn)
  28. eventHub.off("yyy", fn)
  29. eventHub.emit("yyy")
  30. setTimeout(() => {
  31. console.assert(called)
  32. console.log(message)
  33. }, 1000)
  34. }
  35. test1('EventHub可以创建对象')
  36. test2('on 之后 emit会触发on的回调函数')
  37. test3('off卸载监听')

$ ts-node test/index.ts
image.png

优化TS

/src/index.ts

  1. class EventHub {
  2. private cache: { [key: string]: Array<(data?: unknown) => void> } = {}
  3. on(eventName: string, fn: (data?: unknown) => void) {
  4. this.cache[eventName] = this.cache[eventName] || []
  5. this.cache[eventName].push(fn)
  6. }
  7. emit(eventName: string, data?: unknown) {
  8. (this.cache[eventName] || []).forEach(fn => fn(data))
  9. }
  10. off(eventName: string, fn: (data?: unknown) => void) {
  11. this.cache[eventName] = this.cache[eventName] || []
  12. let index = indexOf(this.cache[eventName], fn)
  13. if (index === -1) return
  14. this.cache[eventName].splice(index, 1)
  15. }
  16. }
  17. export default EventHub
  18. /* */
  19. function indexOf(array: Array<(data?: unknown) => void>, item: (data?: unknown) => void) {
  20. if (array === undefined) return -1
  21. let index = -1
  22. for (let i = 0; i < array.length; i++) {
  23. if (array[i] === item) {
  24. index = i
  25. break
  26. }
  27. }
  28. return index
  29. }

/test/index.ts

  1. import EventHub from '../src/index';
  2. type TestCase = (message: string) => void
  3. const test1: TestCase = (message) => {
  4. const eventHub = new EventHub()
  5. console.assert(eventHub instanceof Object === true, "eventHub 是个对象")
  6. console.log(message)
  7. }
  8. const test2: TestCase = (message) => {
  9. const eventHub = new EventHub()
  10. let called = false
  11. eventHub.on("xxx", (data) => {
  12. called = true
  13. console.log("男篮", data)
  14. })
  15. eventHub.emit("xxx", "迈特凯")
  16. setTimeout(() => {
  17. console.assert(called)
  18. console.log(message)
  19. }, 1000)
  20. }
  21. const test3: TestCase = (message) => {
  22. const eventHub = new EventHub()
  23. let called = false
  24. const fn = () => {
  25. called = true
  26. console.log("yyy")
  27. }
  28. eventHub.on("yyy", fn)
  29. eventHub.off("yyy", fn)
  30. eventHub.emit("yyy")
  31. setTimeout(() => {
  32. console.assert(called)
  33. console.log(message)
  34. }, 1000)
  35. }
  36. test1('EventHub可以创建对象')
  37. test2('on 之后 emit会触发on的回调函数')
  38. test3('off卸载监听')