关于js中方法的统一调度管理(队列)

先上代码

function cacheX(){
    this.cache={
        common:[]
    };
}
cacheX.prototype={
    addEvent:function(context,callback,id){
        if(typeof id=="string"){
            if(!this.cache[id]){
                this.cache[id]=[];
            }
            this.cache[id].push({context:context,callback:callback,id:id});
        }else{
            this.cache["common"].push({context:context,callback:callback,id:id});
        }
    },
    exec:function(event,id){
        var i=0,arr=[];
        if(typeof id=="boolean"){
            if(id){//不管id执行所有
                for(name in this.cache){
                    arr=arr.concat(this.cache[name]);
                }
            }else{//执行除了common之外所有的
                for(name in this.cache){
                    if(name!="common"){
                        arr=arr.concat(this.cache[name]);
                    }
                }
            }
        }else{
            arr=id?(this.cache[id]?this.cache[id]:[]):this.cache["common"];
        }
        while(i<arr.length){
            try{
                if(arr[i].context){
                    arr[i].callback.apply(arr[i].context,arguments);
                }else{
                    arr[i].callback(event);
                }
            }catch(e){
                console.error(e);
            }
            i++;
        }
    },
    init:function(){
        var that=this;
        document.addEventListener("click",function(event){
            that.exec(event,true);
        },false);
    },
    clear:function(id){
        if(id){
            if(this.cache[id]){
                this.cache[id]=[];
            }
        }else{
            this.cache["common"]=[];
        }
    },
    clearUnuse:function(arg1){//清理common中无用的对象  该方法只适用于context为vue对象的实例
        var box=arg1||document.body;
        for(name in this.cache){
            let i=0;
            while(i<this.cache[name].length){
                var item=this.cache[name][i];
                if(item.context){
                    if(!box.contains(item.context.$el)){
                        this.cache[name].splice(i,1);
                    }else{
                        i++;
                    }
                }else{
                    this.cache[name].splice(i,1);
                }
            }
        }
    }
}

js中不少方法的执行依赖于同一个先决条件,或者说同一个事件,这个时候我们就可以将这些需要执行的事件统一缓存起来在一个事件里面统一执行。
这样做有不少好处
1.减少可见的事件数量以节约优化资源的使用
2.增加方法执行的可操作性控制方法执行的顺序
3.形成状态管理类的机制(统一缓存起来的数据作为状态管理的资源)
4.突破闭包等范围限制进行数据通信
下面举一些具体的例子

事件队列

1.点击事件click

单存某个子元素上的点击事件因为执行环境单一不具备太多重复可利用性,所以不适合这种模式

因为大多数事件具有冒泡的这个特性,所以很多时候我们都会在点击事件上做事件托管,但是父子元素上的简单事件托管任然不具备太多队列执行的价值

只有添加在document上的点击事件才具有使用队列价值,所有点击事件如果不阻止冒泡都会冒泡到document上,而对于点击事件我个人是不建议做阻止冒泡处理的,可以按照冒泡顺序在相应元素的事件里做过滤操作(比如下拉选择框,颜色选择框之类的弹窗需要在点击除特定元素外的位置后隐藏,这个功能逻辑事件一般都是在document的点击事件里面,如果部分元素冒泡阻止,那么这些功能就会失效)。像这种受众广的事件如果真的集中统一写在一起代码量会太大,不利于维护,这个时候就可以使用队列进行统一管理

/**
 * 添加document点击事件承接方法
* */
global.domClick=new cacheX();
domClick.init();

以上代码中的global是基于webpack环境写成的,在开放环境中可以直接使用var声明
init()方法是内置于对象内部的click事件初始化方法,也可以独立出来,该方法执行的作用域是所有该集合中的方法

2.鼠标滚轮事件,mousemove,mouseup,mouseleave以及resize事件

所有这些受众广多个地方都需要使用的事件都可以使用队列缓存的形式来执行

/**
* 鼠标事件的总体监听
* */
global.mouseEvent=new cacheX();
    
//绑定鼠标事件
if(document.addEventListener){
       document.addEventListener('DOMMouseScroll',mouseEve,false);
}
//IE及其他浏览器
window.onmousewheel = document.onmousewheel=mouseEve;
    
document.addEventListener("mousemove",mouseMove,false);
document.addEventListener("mouseup",mouseUp,false);
document.addEventListener("mouseleave",mouseLeave,false);

//可以调控执行顺序  
function mouseEve(eve){
    //先默认执行common集中的方法
    mouseEvent.exec(eve);
    //在执行除common外所有集中的方法
    mouseEvent.exec(eve,false);
}
function mouseMove(eve){
    mouseEvent.exec(eve,"mousemove");
}
function mouseUp(eve){
    mouseEvent.exec(eve,"mouseup");
}
function mouseLeave(eve){
    mouseEvent.exec(eve,"mouseleave");
}
//浏览器窗口的resize事件
global.Resize=new cacheX();
window.onresize=function(){
    //可以做一些节流处理以避免卡顿现象
    Resize..exec(null,true);
};

数据通信

基于缓存执行机制,我们可以把一些特殊作用域类的方法缓存起来,在需要传地数据的地方使用addEvent添加,在需要执行的时候手动调用exec执行并传递数据

基于vue的项目在组件之间通信的时候,父子通信使用的是props,子组件向父组件传递数据使用的是$emit,但是没有关联的组件之间通信这两种方式都不行,暂时先不论vue提供的vuex方案,使用这种队列的形式就可以解决这种问题

1.一对多数据传递

一个通知方法,多个接受端口

/**
 * 统一的load完成状态管理
 * 生成独立的实例
 * */
global.Loaded=new cacheX();

/**
 *在需要执行数据初始化任务的地方使用这个方法
 *还可以顺带充当domready等事件的效
 *@param data 传递过来的数据
 *@param id 用于识别执行作用域的id 如果为true和false  作用域为最上面代码中标识的作用域
 *this为当前作用域,传递过去之后可以在回调函数里面使用this来直接标识当前作用域,而不用在外面申明一个变量来承接作用域
 */
Loaded.addEvent(this,function(data,id){
      //初始化选择数据
    console.log(this)//this为执行Loaded.addEvent方法的方法的this,等同于与外部作用域一致
},this.iData.prid||this.prid);

/**
*执行数据通知操作
*除了第二个参数需要作为作用域识别外,其他参数均可以作为必要传递的数据
*/
Loaded.exec(data, id, extradata);

2.多对一的数据传递

一个接收端口 多个传递端口
代码与一对多相同,使用方式不同

数据状态管理

在vue项目中使用一对多的数据传递形式时,这个‘’多‘’因为作用域this作为参数传递了过来,使得缓存的数据里面有了所有的组件对象,如果所有需要的组件都使用这些方法进行赋值的话,那我们就可以添加方法根据特定的识别方案获取到任意想要的组件对象,可以操作执行任意组件内部的方法,甚至修改里面的数据

如果一对多和多对一同时使用
那么就可以有统一的值的集合保存方案,将初始化的值集合通过一对多的方式赋值给多;通过多对一的方式将修改后的值汇总到值集合

那么取值赋值的方法可以统一

后记

我没有看过vuex的使用与实现方式
但是感觉应该有相通的地方,可能就是一个简陋版的实现方案吧
只是单存的在实现时觉得这种事情自己也能做,而且也不难,而没有去考虑已经存在解决方案

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容