EventEmitter.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. const name = '@@EventEmitter'
  2. const id_Identifier = '__id__'
  3. /**
  4. * generate random id
  5. */
  6. function randomId() {
  7. return Math.random().toString(36).substr(2, 16)
  8. }
  9. /**
  10. * find id
  11. * @param id
  12. */
  13. function findIndexById(this: CallbackFunc[], id: string) {
  14. return this.findIndex((callback) => callback[id_Identifier] === id)
  15. }
  16. type CallbackFunc = { [id_Identifier]?: string } & ((...dataArray: any[]) => void)
  17. export default class EventEmitter {
  18. [name]: Record<string, CallbackFunc[]>
  19. static Events = {
  20. global: '*',
  21. }
  22. constructor() {
  23. this[name] = {}
  24. }
  25. on(event: string, listener: CallbackFunc) {
  26. let events = this[name]
  27. let container = (events[event] = events[event] || [])
  28. let id = randomId()
  29. let index = -1
  30. listener[id_Identifier] = id
  31. container.push(listener)
  32. return () => {
  33. index = findIndexById.call(container, id)
  34. index >= 0 && container.splice(index, 1)
  35. }
  36. }
  37. off(event: string) {
  38. this[name][event] = []
  39. }
  40. clear() {
  41. this[name] = {}
  42. }
  43. once(event: string, listener: CallbackFunc) {
  44. let self = this
  45. let events = self[name]
  46. let container = (events[event] = events[event] || [])
  47. let id = randomId()
  48. let index = -1
  49. let callback: CallbackFunc = function (...dataArray: any[]) {
  50. index = findIndexById.call(container, id)
  51. index >= 0 && container.splice(index, 1)
  52. listener.apply(self, dataArray)
  53. }
  54. callback[id_Identifier] = id
  55. container.push(callback)
  56. }
  57. emit(event: string, ...dataArray: any[]) {
  58. let self = this
  59. let events = self[name]
  60. let triggers = (events[EventEmitter.Events.global] || []).concat(events[event] || [])
  61. triggers.length > 0 && triggers.map((listener) => listener.apply(self, dataArray))
  62. }
  63. }