标签:
callbacks工具方法,作用是函数回调的统一管理
jQuery.Callbacks = function( options ) {
}
使用:类似于事件绑定,fire之后,之前绑定的方法,都执行。
观察者模式。
function aaa() {
alert(1);
}
function bbb() {
alert(2);
}
function ccc() {
alert(3)
}
var cb = $.Callbacks();
cb.add(aaa);
cb.add(bbb);
cb.add(ccc);
cb.fire(); // 弹出了 1 和 2, 3
add(fun)-->List添加方法。
fire对list数组,进行for循环执行。
/**********************************************************/
function aaa() {
alert(1);
}
(function () {
function bbb() {
alert(2);
}
})();
aaa();
bbb();
//这里无法同时执行弹出1 和 2,因为无法进行统一作用域的管
/**********************************************************/
// 但是Callbacks可以搞定,这个问题。
var cb = $.Callbacks();
function aaa() {
alert(1);
}
cb.add(aaa);
(function () {
function bbb() {
alert(2);
}
cb.add(bbb);
})();
cb.fire(); // 只需要一句就可以了。触发所有
//这里只要回调对象时全局的, 就可以随时向回调函数中添加函数,而后执行。
/**********************************************************/
jQuery.Callbacks = function( options )
options配置参数。四个!!!
* once: will ensure the callback list can only be fired once (like a Deferred)
*
* memory: will keep track of previous values and will call any callback added
* after the list has been fired right away with the latest "memorized"
* values (like a Deferred)
*
* unique: will ensure a callback can only be added once (no duplicate in the list)
*
* stopOnFalse: interrupt callings when a callback returns false
Callbacks的四个参数。
var cb = $.Callbacks();
cb.fire();
cb.fire(); //fire可以执行多次触发的。
(1)once:代表,fire只能触发一次。
cb.fire();
cb.fire(); //不会执行。
让fire执行一次就好了
(2)memory:
var cb = $.Callbacks();
function aaa() {
alert(1);
}
cb.add(aaa);
cb.fire();
function bbb() {
alert(2);
}
cb.add(bbb);
//这段代码执行过后,只能fire出1,不能执行bbb函数
var cb = $.Callbacks(‘memory‘);
function aaa() {
alert(1);
}
cb.add(aaa);
cb.fire();
function bbb() {
alert(2);
}
cb.add(bbb);
//这段代码就是会打印出1 2 。后面的2也可以触发,只要添加就可以执行。
memory是作用到add上面,然后再调用fire。
var cb = $.Callbacks(‘memory‘);
function aaa() {
alert(1);
return false;
}
cb.add(aaa);
cb.fire();
function bbb() {
alert(2);
}
setTimeout(function () {
cb.add(bbb);
}, 1000);
我想了一个例子,应该可以讲的明白,如果变量里面定义了memory,作为初始化,
那么,就执行。当你调用了fire以后,再向内添加add函数的时候,就直接继续执行。
(3)unique:去重复,让函数具有唯一性。作用于add
var cb = $.Callbacks();
function aaa() {
alert(1);
}
cb.add(aaa);
cb.add(aaa);
cb.fire();
//这里触发2次
var cb = $.Callbacks(‘unique‘);
function aaa() {
alert(1);
}
cb.add(aaa);
cb.add(aaa);
cb.fire();
//这里触发1次,重复的函数名,不能放入list,
(4)stopOnFalse
var cb = $.Callbacks(‘stopOnFalse‘);
function aaa() {
alert(1);
return false;
}
cb.add(aaa);
function bbb() {
alert(2);
}
cb.add(bbb);
cb.fire();
//这里只是执行了alert(1)。而alert(2),并没有背执行
//这个变量作用于fire中,判断函数中是否返回false,如果返回false,就立刻推出list循环。
当然还可以接受到组合的形式,比如,memory和once组合的形式,通过空格来分隔开的。
var cb = $.Callbacks(‘once stopOnFalse‘);
Callbacks方法:
add: 将函数,push入 list 中。
remove: 删除
has 检测是否有这个函数,返回false/true
empty 清空数组
disable 全部锁住。禁止,不执行。
lock 锁住。stack=undefined
locked 判断是否锁住
fireWith
fire: --》调用的是fireWith. --》fire = function(data);
fired 判断是否fired
list = [], 用了保存函数列表。
add 添加。
add: function() {
if ( list ) {
// First, we save the current length
var start = list.length;
(function add( args ) {
//这里支持传入多个,cb.add(aaa, bbb);
jQuery.each( args, function( _, arg ) {
var type = jQuery.type( arg );
if ( type === "function" ) {
//判断是不是唯一。unique!!!
if ( !options.unique || !self.has( arg ) ) {
list.push( arg );
}
}
//支持数组形式, cb.add([aaa, bbb]);
else if ( arg && arg.length && type !== "string" ) {
// Inspect recursively
add( arg );
}
});
})( arguments );
// Do we need to add the callbacks to the
// current firing batch?
if ( firing ) {
firingLength = list.length;
//有merory就直接执行。
} else if ( memory ) {
firingStart = start;
fire( memory );
}
}
return this;
},
支持这个:
cb.add(aaa);
cb.add(aaa, bbb);
cb.add([aaa, bbb]);
remove:删除。
对数组进行遍历删除。splice
remove: function() {
if ( list ) {
jQuery.each( arguments, function( _, arg ) {
var index;
while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
list.splice( index, 1 );
// Handle firing indexes
if ( firing ) {
if ( index <= firingLength ) {
firingLength--;
}
if ( index <= firingIndex ) {
firingIndex--;
}
}
}
});
}
return this;
},
cb.add(aaa);
cb.add(bbb);
cb.add(ccc);
cb.remove(bbb);
cb.fire(); // 就只有aaa 和 ccc
fire:执行。
fire = function( data ) {
memory = options.memory && data;
fired = true;
firingIndex = firingStart || 0;
firingStart = 0;
firingLength = list.length;
firing = true; //触发开始
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
memory = false; // To prevent further calls using add
break;
}
}
firing = false; //触发结束
if ( list ) { //判断list
if ( stack ) {
if ( stack.length ) { //stack的长度部位空,
//递归调用
fire( stack.shift() ); //将栈中的第一个返回。并且fire
}
}
//如果有记忆,
else if ( memory ) {
//列表清空
list = [];
} else {
self.disable();
}
}
},
//Call all callbacks with the given context and arguments
fireWith: function( context, args ) {
if ( list && ( !fired || stack ) ) {
args = args || [];
//如果是数组,就转换为对象。
args = [ context, args.slice ? args.slice() : args ];
if ( firing ) {
stack.push( args );
} else {
fire( args );
}
}
return this;
},
// Call all the callbacks with the given arguments
fire: function() {
self.fireWith( this, arguments );
return this;
},
// To know if the callbacks have already been called at least once
fired: function() {
return !!fired;
}
stack = !options.once && [], //这里定义了一个栈
firing 事件触发的时候。
fireWith:
fireWith: function( context, args ) {
if ( list && ( !fired || stack ) ) {
args = args || [];
args = [ context, args.slice ? args.slice() : args ];
//这里,如果是firing时,就讲fire压入栈
if ( firing ) {
stack.push( args );
} else {
fire( args );
}
}
return this;
},
有个例子
var cb = $.Callbacks();
var singal = true;
function aaa() {
alert(1);
if (singal) {
cb.fire(); //stack.push( args );
singal = false;
}
}
cb.add(aaa);
function bbb () {
alert(2);
}
cb.add(bbb);
cb.fire();
弹出顺序是1,2 1,2.
这个是在fire中实现的。
if ( list ) { //判断list
if ( stack ) {
if ( stack.length ) { //stack的长度部位空,
//递归调用
fire( stack.shift() ); //将栈中的第一个返回。并且fire
}
}
//如果有memory的时候,就清空数组。
else if ( memory ) {
//列表清空
list = [];
} else {
self.disable();
}
}
标签:
原文地址:http://www.cnblogs.com/hgonlywj/p/4852964.html