首页 技术 正文
技术 2022年11月10日
0 收藏 552 点赞 3,591 浏览 3989 个字

在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数。如下:

this.foo = function(args,callbackFn) {
//do something
//then if callbackFn is a function
callbackFn();
};

或者在初始化的传入config。

 function SDK(config) {
var configs = {
onInit: function() {
},
onFoo: function () {
},
// on....
};
//合并参数
configs = $.extend(configs, config);
this.foo = function (args) {
//do something
configs.onFoo();
};
}

但问题来了,随着函数越多,第一种方式就显得很烦,每个方法的参数后面要跟一个或者多个回调函数,代码显得不干净,而且只有用户调用的时候才会执行回调,对于没有暴露给用户的方法就用不上。第二种方式,函数越多,config就越长,构造代码显得难看,另一方面就是一个方法只会触发一个回调。最后使用了下面的方式

事件管理

先定义一个事件管理器,主要思路是让每一个事件类型对应一个回调列表,这样可以让外部对同一个事件关联多次。取消某个关联就是在该事件类型的函数列表中移除某个回调函数。触发就是把列表中函数全部执行一遍。当然还带上了参数。

 var eventManger = {
handlers: {},
//类型,绑定事件
addHandler:function(type,handler) {
if (typeof this.handlers[type] == "undefined") {
this.handlers[type] = [];//每个事件都可以绑定多次
}
this.handlers[type].push(handler);
},
removeHandler:function(type, handler) {
var events = this.handlers[type];
for (var i = 0, len = events.length; i < len; i++) {
if (events[i] == handler) {
events.splice(i, 1);
break;
}
}
},
trigger: function (type) {
if (this.handlers[type] instanceof Array) {
var handlers = this.handlers[type];
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0, len = handlers.length; i < len; i++) {
handlers[i].apply(null, args);
}
}
}
};

然后在sdk中公布关联和移除的方法:

 //给外部绑定事件
this.on = function(type, event) {
eventManger.addHandler(type,event);
};
//移除事件
this.off = function(type, event) {
eventManger.removeHandler(type, event);
};

在执行的过程中分别触发事件:

           this.init = function() {
//do init
eventManger.trigger('init');
};
this.start = function() {
//do start
eventManger.trigger('start');
};
this.connect = function() {
eventManger.trigger('connect');
};
this.messages = function() {
var msgs = [];
msgs.push("你好吗");
msgs.push("我很好");
eventManger.trigger('messages',msgs);
};
this.disconnect = function() {
eventManger.trigger('disconnect');
};

那用户在使用的时候就比较方便了。

//绑定connect
sdk.on('connect', function () {
console.log('connect');
});
//绑定messages
sdk.on('messages', function (data) {
if (!data) return; if (data instanceof Array) {
for (var i = 0; i < data.length; i++) {
console.log(data[i]);
}
} else {
console.log(data);
}
});

还可以先绑定,移除再绑定。

var oninit = function() {
console.log('init...');
};
sdk.on('init', oninit);
sdk.on('init', function () {
console.log('other init');
});
sdk.off('init', oninit);
sdk.init();

全部代码:

    function SDK() {            var eventManger = {
handlers: {},
//类型,绑定事件
addHandler:function(type,handler) {
if (typeof this.handlers[type] == "undefined") {
this.handlers[type] = [];//每个事件都可以绑定多次
}
this.handlers[type].push(handler);
},
removeHandler:function(type, handler) {
var events = this.handlers[type];
for (var i = 0, len = events.length; i < len; i++) {
if (events[i] == handler) {
events.splice(i, 1);
break;
}
}
},
trigger: function (type) {
if (this.handlers[type] instanceof Array) {
var handlers = this.handlers[type];
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0, len = handlers.length; i < len; i++) {
handlers[i].apply(null, args);
}
}
}
};
//给外部绑定事件
this.on = function(type, event) {
eventManger.addHandler(type,event);
};
//移除事件
this.off = function(type, event) {
eventManger.removeHandler(type, event);
}; this.init = function() {
//do init
eventManger.trigger('init');
};
this.start = function() {
//do start
eventManger.trigger('start');
};
this.connect = function() {
eventManger.trigger('connect');
};
this.messages = function() {
var msgs = [];
msgs.push("你好吗");
msgs.push("我很好");
eventManger.trigger('messages',msgs);
};
this.disconnect = function() {
eventManger.trigger('disconnect');
}; this.autoRun = function() {
this.init();
this.start();
this.connect();
this.messages();
this.disconnect();
}; } var sdk = new SDK();
var oninit = function() {
console.log('init...');
};
sdk.on('init', oninit);
sdk.on('start', function () {
console.log('start');
});
sdk.on('connect', function () {
console.log('connect');
});
sdk.on('messages', function (data) {
if (!data) return; if (data instanceof Array) {
for (var i = 0; i < data.length; i++) {
console.log(data[i]);
}
} else {
console.log(data);
}
});
sdk.on('disconnect', function () {
console.log('disconnect');
}); sdk.autoRun();
sdk.on('init', function () {
console.log('other init');
});
sdk.off('init', oninit);
sdk.init();

执行结果:

JavaScript  事件管理

还可以扩展一些方法once() 、removeListener() 、removeAllListeners()֖等

小结:事件的处理方式更加简洁且更有扩展性。jquery的事件机制没有将事件监听函数绑定到DOM元素上,而是基于数据缓存模块来管理的。这里借鉴了下,对同一事件类型type的所有监听对象handleObj构成监听对象数组handles。因为没有涉及到dom操作,所以相对也简单些。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297