Cocos Creator 3.x 共建生态 - Event

interface IEventsMap { [key: string]: any }

type Handler<T = unknown> = (data: T) => void

export default class Event<Events extends IEventsMap> {

  key = new Proxy<{ [key in keyof Events]: key }>(Object.create(null), {

    get: (_, key) => key

  })

  private events = new Map<keyof Events, Array<[unknown, Handler<Events[keyof Events]>]>>()

  private getHandlers<Key extends keyof Events>(type: Key) {

    let handlers = this.events.get(type)

    if (!handlers) {

      handlers = []

      this.events.set(type, handlers)

    }

   

    return handlers

  }

  on<Key extends keyof Events>(type: Key, handler: Handler, target?: unknown) {

    this.getHandlers(type).push([target, handler])

  }

  emit<Key extends keyof Events>(type: Key, data: Events[Key]) {

    this.getHandlers(type).forEach(([target, handler]) => {

      target ? handler.call(target, data) : handler(data)

    })

  }

  off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>, target?: unknown) {

    if (handler) {

      const handlers = this.getHandlers(type)

      const index = handlers.findIndex(value => {

        return (value[0] === target && value[1] === handler)

      })

      handlers.splice(index >>> 0, 1)

    } else {

      this.events.set(type, [])

    }

  }

  once<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>, target?: unknown) {

    const callbackWrap = (data: Events[Key]) => {

      target ? handler.call(target, data) : handler(data)

      this.off(type, handler, target)

    }

    this.on(type, callbackWrap, target)

  }

}
3赞

使用时,有各种约束提示

点赞点赞:+1:

提个建议啊,事件绑定的时候,很多情况需要绑定对象,比如A和B都有事件E,你在A节点off的时候直接吧E事件赋值空了的话,B节点也会受影响,建议加上校验

感觉和我这个差不多

https://www.cnblogs.com/muzzik/p/17044999.html

很抱歉,这应该是使用不当

是的,这个我忘记加了绑定上下文了,我现在考虑要不要加上, 因为箭头函数可以处理指向问题,但是继承又是问题

我在想使用装饰器处理,但是发现继承的this指向有问题,大佬有什么好的建议吗

直接继承 cc.EventTarget,最好的选择,也是最安全的做法

甚至实例化也可以直接用 cc.EventTarget,继承的类型只用作类型提示,不过这样不能用 key 了

赞同你的看法,EventTarget可以不必重复造轮子

EventTarget挺好的

额。。。,我不知道有这个

已支持上下文的