js里的事件管理

这篇文章展示了如何在JavaScript中实现原生的事件管理功能,包括同步和异步的事件处理。通过HandlerBase类实现了同步事件处理,通过AsyncEventController类实现了异步事件处理,利用requestAnimationFrame进行帧同步的事件调度。
摘要由CSDN通过智能技术生成

js原生是没有事件管理功能的,也看到了网上的一些比如js-signals或者EventEmitter等第三方库,但还是想自己写一套,同时支持同步和异步的。废话少说,上代码

下图为同步的事件处理

function HandlerBase(){
    this._handlerDict = {};
}

Object.assign(HandlerBase.prototype, {
    addHandler: function(type, callback, thisObj){
        let list = this._handlerDict[type];
        if(!list) {
            list = [];
            this._handlerDict[type] = list;
        }
        list.push({callback, thisObj});
    },
    removeHandler: function(type, callback, thisObj){
        let list = this._handlerDict[type];
        if(!list || list.length <= 0 ) return;
        for(let i=0; i < list.length; ++i ) {
            let obj = list[i];
            if(obj.callback === callback && obj.thisObj === thisObj) {
                list.splice(i, 1);
                i--;
                if(list.length <= 0 ) {
                    delete this._handlerDict[type];
                    break;
                }
            }
        }
    },
    _dispatch: function(type, value){
        let list = this._handlerDict[type];
        if(!list || list.length <= 0 ) return;
        list.forEach((item)=>{
            item.callback.apply(item.thisObj, [value]);
        });
    },
});

接下来是异步的




/**
 * 异步的事件处理机制
 */
function AsyncEventController(){
    this._handlerDict = {};
    this._dispatchList = [];
    this._enabled = false;
    this._init();
}

Object.assign(AsyncEventController.prototype, {
    _init: function(){
    },
    addHandler: function(type, callback, thisObj){
        let list = this._handlerDict[type];
        if(!list) {
            list = [];
            this._handlerDict[type] = list;
        }
        list.push({callback, thisObj});
    },
    removeHandler: function(type, callback, thisObj){
        let list = this._handlerDict[type];
        if(!list || list.length <= 0 ) return;
        for(let i=0; i < list.length; ++i ) {
            let obj = list[i];
            if(obj.callback === callback && obj.thisObj === thisObj) {
                list.splice(i, 1);
                i--;
                if(list.length <= 0 ) {
                    delete this._handlerDict[type];
                    break;
                }
            }
        }
    },
    _onEnterFrame: function(time){
        while(this._dispatchList.length > 0 ) {
            const {type, value} = this._dispatchList.pop();
            this._doDispatch(type, value);
        }
        this._enabled = false;
    },
    _dispatch: function(type, value){
        this._dispatchList.push({type, value});
        if(!this._enabled){
            requestAnimationFrame(this._onEnterFrame.bind(this));
            this._enabled = true;
        }
    },
    _doDispatch: function(type, value){
        let list = this._handlerDict[type];
        if(!list || list.length <= 0 ) return;
        list.forEach((item)=>{
            item.callback.apply(item.thisObj, [value]);
        });
    },
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值