memory:保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred)。
回调函数是从异步队列Deferred分离出来的,所以很多的接口设计都是为了契合Deferred接口,memory用的很多,这个缓存的设计这里提及一下
主要是用来实现deferred的异步收集与pipe管道风格的数据传递的,具体在Deferred有详解,这里大概了解下作用范围。
memory这个有点不好理解,我们还是通过列子说明下,看下面的代码:
function fn1(val) { console.log('fn1 says:' + val); } function fn2(val) { console.log('fn2 says ' + val); } function fn3(val){ console.log("fn3 says " + val); } /* var cbs = $.Callbacks("memory"); cbs.add(fn1); cbs.fire('foo'); console.log('..........'); cbs.add(fn2); cbs.fire('bar'); console.log('..........'); cbs.add(fn3); cbs.fire('aaron');*/ function callbacks(options){ var list = []; var self; var memory; var firingStart; function _fire(data){ memory = options === 'memory' && data;//===>&&>= firingIndex = firingStart || 0; firingStart = 0;//改变firingStart,之后的fire还是从0开始。 firingLength = list.length; for(; list && firingIndex < firingLength; firingIndex++){ list[firingIndex](data); } }; self = { add: function(fn){ var start = list.length; list.push(fn); if(memory){ firingStart = start;//改变firingStart _fire(memory); } }, fire: function(args){ if(list){ _fire(args); if(options === "once"){ list = undefined; } } } }; return self; } var cc = callbacks("memory"); cc.add(fn1); cc.fire("111"); console.log("..............."); cc.add(fn2); cc.fire("222");
unique:
function fn1(val) { console.log('fn1 says:' + val); } function fn2(val) { console.log('fn2 says ' + val); } function fn3(val){ console.log("fn3 says " + val); } /*var cbs = $.Callbacks("unique"); cbs.add(fn1); cbs.add(fn1); cbs.add(fn1); cbs.fire('foo'); console.log('..........');*/ /*cbs.add(fn2); cbs.fire('bar'); console.log('..........'); cbs.add(fn3); cbs.fire('aaron');*/ function callbacks(options){ var list = []; var self; var memory; var firingStart; function _fire(data){ memory = options === 'memory' && data;//===>&&>= firingIndex = firingStart || 0; firingStart = 0;//改变firingStart,之后的fire还是从0开始。 firingLength = list.length; for(; list && firingIndex < firingLength; firingIndex++){ list[firingIndex](data); } }; self = { add: function(fn){ var start = list.length; if(options === "unique"){ if(list.indexOf(fn) === -1){ list.push(fn); } }else{ list.push(fn); } if(memory){ firingStart = start;//改变firingStart _fire(memory); } }, fire: function(args){ if(list){ _fire(args); if(options === "once"){ list = undefined; } } } }; return self; } var cc = callbacks("unique"); cc.add(fn1); cc.add(fn1); cc.add(fn1); cc.fire("111");
stopOnfalse:
function fn1(val) { console.log('fn1 says:' + val); return false; } function fn2(val) { console.log('fn2 says ' + val); return false; } function fn3(val){ console.log("fn3 says " + val); } /*var cbs = $.Callbacks("stopOnFalse"); cbs.add(fn1); cbs.fire('foo'); console.log('..........'); cbs.add(fn2); cbs.fire('bar'); console.log('..........'); cbs.add(fn3); cbs.fire('aaron');*/ /*cbs.add(fn2); cbs.fire('bar'); console.log('..........'); ;*/ function callbacks(options){ var list = []; var self; var memory; var firingStart; function _fire(data){ memory = options === 'memory' && data;//===>&&>= firingIndex = firingStart || 0; firingStart = 0;//改变firingStart,之后的fire还是从0开始。 firingLength = list.length; for(; list && firingIndex < firingLength; firingIndex++){ if(list[firingIndex](data) === false && options === 'stopOnFalse'){ break; }; } }; self = { add: function(fn){ var start = list.length; if(options === "unique"){ if(list.indexOf(fn) === -1){ list.push(fn); } }else{ list.push(fn); } if(memory){ firingStart = start;//改变firingStart _fire(memory); } }, fire: function(args){ if(list){ _fire(args); if(options === "once"){ list = undefined; } } } }; return self; } var cc = callbacks("stopOnFalse"); cc.add(fn1); cc.fire("111"); cc.add(fn2); cc.fire("222");