在模块化的应用程序开发中,大多数情况一个模块使用一个回调函数就够了,如果遇到需要多回调函数的情况,如一个使用了插件机制的web相册系统。
A是核心模块,负责本地缓存与远程数据加载、分页、切换照片、历史记录管理等操作,插件B、C、D、…数目与结构并不确定,此时如何在A执行插件的回调函数呢?我们可以自定义事件的方式来绑定并执行多个回调函数,类似addEventListener (DOM)、attachEvent (IE)方式,在A执行关键操作的时候总是触发一个固定名称自定义事件,而外部插件任意可以向其绑定回调函数,实现代码:
/**
* 回调函数机制
* 支持多个回调函数绑定
* @author tangbin
* @see http://www.planeart.cn/?p=1182
* @namespace
*/
var callback = (function () {
var that = this,
cache = {},
fName = '${callback}',
fVal = 1;
/**
* @scope callback
*/
return {
/**
* 绑定回调函数
* @example var loadEndFn = function (photoId, photoIndex) {
* // code..
* };
* callback.bind('getData', loadEndFn);
* @param {String} 名称
* @param {Function} 要绑定的回调函数
*/
bind: function (name, callback) {
!cachename && (cachename = {});
!callbackfName && (callbackfName = fVal ++);
cachenamecallbackfName = callback;
},
/**
* 移除回调函数
* @example var loadEndFn = function (photoId, photoIndex) {
* // code..
* };
* callback.unbind('getData', loadEndFn);
* @param {String} 名称
* @param {Function} 要卸载的回调函数
*/
unbind: function(name, callback) {
callback === undefined ?
delete cachename :
callbackfName && (delete cachenamecallbackfName);
},
/**
* 触发回调函数
* @example var photoId = 34356, photoIndex = 0;
* callback.trigger('getData', photoId, photoIndex);
* @param {String} 名称
* @param {Array} (可选)传递给事件处理函数的附加参数
*/
trigger: function (name, data) {
var i, ret, callbacks = cachename;
if (callbacks) for (i in callbacks) ret = callbacksi.apply(that, data);
return ret;
}
};
})();
当然,也可以猥琐的为“on”类型的事件提供多回调函数绑定(有些javascript框架的事件机制就基于此来解决跨浏览器兼容),演示。