菜鸟不是很理解官方demo源码里 ClientEvent.ts的实现原理

// ClientEvent.ts
import { _decorator } from "cc";

const { ccclass, property } = _decorator;

@ccclass("ClientEvent")

export class ClientEvent {

    private static _handlers: { [key: string]: any[] } = {};

    /**

     * 监听事件

     * @param {string} eventName 事件名称

     * @param {function} handler 监听函数

     * @param {object} target 监听目标

     */

    public static on (eventName: string, handler: Function, target: any) {

        let objHandler: {} = { handler: handler, target: target };

        let handlerList: Array<any> = ClientEvent._handlers[eventName];

        if (!handlerList) {

            handlerList = [];

            ClientEvent._handlers[eventName] = handlerList;

        }

        for (let i = 0; i < handlerList.length; i++) {

            if (!handlerList[i]) {

                handlerList[i] = objHandler;

                return i;

            }

        }

        handlerList.push(objHandler);

        return handlerList.length;

    }

    /**

     * 取消监听

     * @param {string} eventName 监听事件

     * @param {function} handler 监听函数

     * @param {object} target 监听目标

     */

    public static off (eventName: string, handler: Function, target: any) {

        let handlerList = ClientEvent._handlers[eventName];

        if (!handlerList) {

            return;

        }

        for (let i = 0; i < handlerList.length; i++) {

            let oldObj = handlerList[i];

            if (oldObj.handler === handler && (!target || target === oldObj.target)) {

                handlerList.splice(i, 1);

                break;

            }

        }

    }

    /**

     * 分发事件

     * @param {string} eventName 分发事件名

     * @param  {...any} params 分发事件参数

     */

    public static dispatchEvent (eventName: string, ...args: any) {

        let handlerList = ClientEvent._handlers[eventName];

        let args1 = [];

        let i;

        for (i = 1; i < arguments.length; i++) {

            args1.push(arguments[i]);

        }

        if (!handlerList) {

            return;

        }

        for (i = 0; i < handlerList.length; i++) {

            let objHandler = handlerList[i];

            if (objHandler.handler) {

                objHandler.handler.apply(objHandler.target, args1);

            }

        }

    }

}
// 调用
import { ClientEvent } from './../framework/clientEvent';
……
// 我不理解这样是怎么实现监听和取消的的(难道是我漏看了哪里?)
ClientEvent.on(Constant.GAMEOVER_TYPE.GAME_WIN, this.gameWin, this);
ClientEvent.off(Constant.GAMEOVER_TYPE.GAME_WIN, this.gameWin, this);

希望各路大神指教!

1赞

不是很难理解,理解不了的话,就慢慢用的时候就理解了。
on声明一个标志为key的的回调函数;
off取消标志为key的的回调函数;
dispatchEvent 触发回调函数;

有些明白了,是我走进了误区
我一直想把它跟比如this.node.on(……)联系起来
感谢感谢

其实原理都一样,那是引擎内部的。这个算是自己定义的,为啥要搞这个呢,是因为你可以单个或在多个地方声明多个key一样的回调函数,只要你触发,所有地方的回调函数都会执行。

明白了,非常感谢,可以安心睡觉了 :smile:

所有的监听都是维护了 一个函数列表触发事件之后遍历回调函数

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。