zoukankan      html  css  js  c++  java
  • 事件模型-发布订阅模式

    订阅者模式
    实际举例,比如我想要一个妹子,于是我和媒婆说(我向媒婆订购妹子),媒婆那边有好多妹子,于是一个一个依次给我发放;
    实际上就是事件模型
    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

  • 相关阅读:
    消息队列 RPC之间的区别与联系
    RabbitMQ, ZeroMQ, Kafka 是一个层级的东西吗, 相互之间有哪些优缺点?
    嵌入式软件开发工程师谈软件架构的设计
    值得推荐的C/C++框架和库 (真的很强大)
    10.2-嵌入式系统库资源集合
    正则表达式
    vscode代码阅读
    vscode配置
    VSCode的开发环境zsESampleLinux
    MySQL与宿主Linux之间交互式执行命令
  • 原文地址:https://www.cnblogs.com/fqh123/p/14258785.html
Copyright © 2011-2022 走看看