一、jQuery 的 Callbacks是一个基本的操作,异步等很多功能都依赖Callbacks,简单写下其使用
var callbacks = $.Callbacks(); callbacks.add(function(data){alert(data)}); callbacks.fire("1"); alert: 1
二、实现
思路:显然是一个订阅发布的一个模式 写一个list add的时候 function先放进去,fire的时候执行,就直接写了:
J.extend("Callbacks",function(mode){ //只做了个 once var list = [], firing, firingIndex, firingStart, fire = function(context, data){ firing = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; for(; list && firingIndex < firingLength; firingIndex++){ var ret = list[firingIndex].apply(context, data); if ( ret === false ){ break; } } if(mode == "once"){ list.length = 0; } firing = false; }, self = { add:function(){ //fn [fn1, fn2] if(list){ Array.prototype.push.apply(list, arguments); } return this; }, fire:function(){ if(list.length && !firing){ fire(this, arguments); }; }, remove:function(){ var i, index; for( i = 0; i < arguments.length; i++ ){ var arg = arguments[i]; if((index = list.indexOf(arg)) > -1){ list.splice(index, 1); } if (firing) { if (index <= firingLength) { firingLength--; } if (index <= firingIndex) { firingIndex--; } } } } }; return self; });
这里的 J.extend 是使用上面自己实现的 “J”核心, 可以把 Callbacks 直接填进去,实现没什么难的,当然这里也使用 了 Array.prototype.push.apply(list, arguments); 这样的方法, 没用过的可以抄过去, 还有Math.max.apply(Math,[])等等。
测试一下
var callbacks = J.Callbacks("once"); callbacks.add(function(data){ alert(data); },function(data){ alert(data + 1); }).fire(1); alert: 1 alert: 2