这一小节我们来讲一下once。
once的作用确保回调列表只执行(.fire())一次(像一个递延 Deferred),如下代码:
function fn1(val){
console.log('fn1 says ' + val);
}
var cbs = $.Callbacks('once');
cbs.add(fn1);
cbs.fire('foo');
cbs.fire('foo');
结果你会发现cbs.fire('foo')只执行了一次。
fn1 says foo //只显示一次
once定义是很明确的,确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred),所以针对这种once的处理可以有多种不同的途径实现。
1、add的时候抛弃
2、在fire的时候抛弃多个。
但是jQuery是在执行第一个fire的时候直接给清空list列表了,然后在add的地方给判断下list是否存在,从而达到这样的处理。
function Callbacks(options) { var list = []; var self; self = { add: function(fn) { list.push(fn) }, fire: function(args) { if (list) { list.forEach(function(fn) { fn(args); }) if (options === 'once') { list = undefined; } } } } return self; }
在fire之后,判断参数是否为once,直接把list给清理掉,所以之后的所有fire都被抛弃掉了,而从达到了once的效果。
jQuery.Callbacks的处理
在fire中调用了 self.disable(); 方法
// 禁用回调列表中的回调。 disable: function() { list = stack = memory = undefined; return this; },
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="http://img1.sycdn.imooc.com//down/540812440001e40e00000000.js" type="text/javascript"></script> <script src="http://img1.sycdn.imooc.com//down/541f6ff70001a0a500000000.js" type="text/javascript"></script> <title></title> </head> <body> <script type="text/javascript"> function Callbacks(options) { var list = []; var self; self = { add: function(fn) { list.push(fn) }, fire: function(args) { if(list){ list.forEach(function(fn) { fn(args); }) if(options === 'once'){ list = undefined; } } } } return self; } function fn1(val) { show('fn1 says:' + val); } function fn2(val) { show('fn2 says ' + val); } var cbs = Callbacks('once'); cbs.add(fn1); cbs.fire('foo'); cbs.fire('foo'); </script> </body> </html>