事件模型-发布订阅模式

订阅者模式
实际举例,比如我想要一个妹子,于是我和媒婆说(我向媒婆订购妹子),媒婆那边有好多妹子,于是一个一个依次给我发放;
实际上就是事件模型
1.有一个event对象
2.on、off、emit方法
实现事件模型,思考怎么用?

1.event是一个全局对象s
event.on('事件名','处理函数'),订阅事件
 1.事件可以连续订阅
 2.可以移除event.off()
     1.移除所有
     2.移除某一个类型的事件
     3.移除某一个类型的某一个处理函数
3.写别的代码
4.event.emit('事件名','参数');先前注册的事件处理函数就会依次调用

代码实现:

复制代码
// 我们需要一个event对象,拥有on、off、emit方法
var event = (function(){//采用闭包是用来存储注册的事件eventObjs
    eventObjs = {};
    return{
        /**注册事件,可以连续注册,可以注册多个事件*/
        on:function(type,handler){
            // 如果注册过对应type事件,就直接把handler加在队列中,如果没有对应type类型,就先创建一个type类型的队列(数组),然后再handler添加进去
            // 不得不说,这代码很漂亮
            ( eventObjs[ type ] || ( eventObjs[ type ] = [] ) ).push(handler);
        },
        /**移除事件,
         * -如果没有参数,移除所有事件,
         * -如果只带有 事件名 参数,就移除这个事件名下的所有事件,
         * -如果带有事件名 参数和事件处理函数名,那么久表示移除对应事件名下的某一个处理事件,
        */
        off:function(type,handler){
            if(arguments.length === 0){//没有参数,移除所有事件
                eventObjs = {};
            }else if(arguments.length === 1){//说明只有type:事件的类型,要移除此事件名下的所有处理函数
                eventObjs[ type ] = [];
            }else if(arguments.length === 2){//移除type事件的handler函数
                // 使用循环移除所有的 该函数 对应的 type事件
                let _events = eventObjs[ type ];
                if(!_events) return;
                // 因为移除意向后,数组长度会自动变短,倒着循环,数组的序号不会受到影响
                for( let i = _events.length - 1;i >= 0;i-- ){
                    if( _events[i] === handler){
                        _events.splice(i,1);
                    }
                }
            }
        },
        /**发射事件,触发事件,包装参数,传递给事件处理函数*/
        emit:function(type){
            let args = Array.prototype.slice.call(arguments,1);//拿到arguments从1开始后的所有参数,返回的是数组
            let _events = eventObjs[ type ];
            if(!_events) return;
            for(let i = 0;i < _events.length;i++){
                // 如果要绑定上下文,就需要用到call或apply
                _events[i].apply(null,args);
            }
        },
    }

})();
复制代码

使用:

复制代码
event.on('click',() => console.log("第一个click事件"));
console.log(1);
console.log(1);
event.on('click',() => console.log("第二个click事件"));
console.log(1);
console.log(1);
console.log(1);
event.emit('click');
console.log(1);
复制代码

补充:

复制代码
// js中基本类型是比较值
// 引用类型是比较地址
// 引用类型与基本类型比较,将其转换为基本类型再比较,如果是 === 严格等于 是不转换类型的
let a = b = {};
let c = {};
console.log(a == b);//true
console.log(a === b);//true
console.log(a == c);//false
function f(){};
let d = f;
console.log(d == f);//true
console.log({} == {});//false
console.log([] == []);//false
console.log((()=>{}) == (()=>{}));//false
复制代码

 

 

posted @   古墩古墩  Views(370)  Comments(0Edit  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2020-01-10 移动h5开发中遇到的问题
2019-01-10 主动触发input框的失去焦点事件,阻止输入法跳出
点击右上角即可分享
微信分享提示